大家好日子。
我有一个旋转C#和线程的问题,我还是线程新手,我有一个基于线程的赋值。我的目标是让用户指定一定数量的线程,并根据这个数量,即应用程序需要使用多少线程来完成任务。
我的任务是使用中值3 x 3矩阵模糊图像。那部分我设法下降(可能不是最有效的代码)但现在我需要让可变数量的线程运行模糊方法,我完全迷失了它。
这是我的方法:
public void Blur(Bitmap bmpInput)
{
Bitmap temp;
float sumR, sumB, sumG;
Color c;
temp = bmpInput;
for (int i = 0; i <= bmpInput.Width - 3; i++)
for (int j = 0; j <= bmpInput.Height - 3; j++)
{
sumB = 0;
sumG = 0;
sumR = 0;
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
c = bmpInput.GetPixel(x, y);
sumR = sumR + c.R;
sumG = sumG + c.G;
sumB = sumB + c.B;
}
byte colorR = (byte)(sumR / 9);
byte colorG = (byte)(sumG / 9);
byte colorB = (byte)(sumB / 9);
temp.SetPixel(i + 1, j + 1, Color.FromArgb(colorR, colorG, colorB));
}
temp.Save("C:\\Users\\Username\\Desktop\\whatever.jpg");
}
这是另一种做同样事情的方法(虽然快一点)
public static Bitmap MedianFiltering(Bitmap bm)
{
List<byte> termsList = new List<byte>();
byte[,] image = new byte[bm.Width, bm.Height];
//applying Median Filtering
for (int i = 0; i <= bm.Width - 3; i++)
for (int j = 0; j <= bm.Height - 3; j++)
{
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
termsList.Add(image[x, y]);
}
byte[] terms = termsList.ToArray();
termsList.Clear();
Array.Sort<byte>(terms);
Array.Reverse(terms);
byte color = terms[4];
bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
}
return bm;
}
此时我正在考虑“分割”图像并让每个线程将该方法应用于图像的一部分。
我的问题:如何在我的程序中实现线程。我之前从未使用过线程,大多数在线指南对我来说都像希腊语。
答案 0 :(得分:1)
我们可以使用具有排队概念的任务库。由于任务库有效地使用核心。 让我们使用全局BlockingCollection来存储所有传入的Bitmap图像。
// BlockingCollection是threadSafe Collection
BlockingCollection<Bitmap> incomingBitmaps = new BlockingCollection<Bitmap>();
还有一个处理过的位图图像的全局BlockingCollection。
BlockingCollection<Bitmap> processedBitmaps = new BlockingCollection<Bitmap>();
让我们有三种方法负责
用于创建任务/线程
读取传入的位图并存储到incomingBitmaps队列
已处理的位图将被处理为processedBitmaps队列
BlockingCollection<Bitmap> incomingBitmaps = new BlockingCollection<Bitmap>();
BlockingCollection<Bitmap> processedBitmaps = new BlockingCollection<Bitmap>();
public static void SpawnThreads()
{
List<Task> ReaderTasks = new List<Task>();
TaskFactory tfReader = new TaskFactory();
public List<Task> ProcessTasks = new List<Task>();
public TaskFactory tfProcess = new TaskFactory();
//you can create threads as many you want
for (int i = 0; i <2; i++)
{
ReaderTasks .Add(tfReader.StartNew(() => ReadBitmaps());
}
for (int i = 0; i <5; i++)
{
ProcessTasks.Add(tfProcess.StartNew(() => MedianFiltering());
}
}
public static void ReadBitmaps()
{
//logic to get bitmap images
Bitmap bmp= GetBitmapImage();
incomingBitmaps.Add(bmp);
}
public static void MedianFiltering()
{
foreach (var bm in incomingBitmaps.GetConsumingEnumerable())
{
List<byte> termsList = new List<byte>();
byte[,] image = new byte[bm.Width, bm.Height];
//applying Median Filtering
for (int i = 0; i <= bm.Width - 3; i++)
for (int j = 0; j <= bm.Height - 3; j++)
{
for (int x = i; x <= i + 2; x++)
for (int y = j; y <= j + 2; y++)
{
termsList.Add(image[x, y]);
}
byte[] terms = termsList.ToArray();
termsList.Clear();
Array.Sort<byte>(terms);
Array.Reverse(terms);
byte color = terms[4];
bm.SetPixel(i + 1, j + 1, Color.FromArgb(color, color, color));
}
processedBitmaps.Add(bm);
}
}
我们可以将processedBitmaps用于UI绑定。