報錯:對象當前正在其他地方使用
System.Drawing.Bitmap如果跨線程使用,或者同時被多方調用,就會報錯對象當前正在其他地方使用
解決方案是新開線程就新建一個Bitmap副本,並且保證一個Bitmap對象同時只被一個地方使用
復現這個問題的例子如下:
string file="one image path";
System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(file);
Task.Run(() =>
{
try
{
while (true)
{
for (int i = 0; i < bmp.Width; i++)
for (int j = 0; j < bmp.Height; j++)
{
var c1 = bmp.GetPixel(i, j);
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{
}
});
Task.Run(() =>
{
try
{
while (true)
{
for (int i = 0; i < bmp.Width; i++)
for (int j = 0; j < bmp.Height; j++)
{
var c1 = bmp.GetPixel(i, j);
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{
}
});
正確的使用方式是:
string file="one image path";
System.Drawing.Bitmap bmp1 = new System.Drawing.Bitmap(file);
Task.Run(() =>
{
try
{
var cpbmp1 = (Bitmap)bmp1.Clone();
while (true)
{
for (int i = 0; i < cpbmp1.Width; i++)
for (int j = 0; j < cpbmp1.Height; j++)
{
var c1 = cpbmp1.GetPixel(i, j);
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{
}
});
Task.Run(() =>
{
try
{
var cpbmp2 = (Bitmap)bmp1.Clone();
while (true)
{
for (int i = 0; i < cpbmp2.Width; i++)
for (int j = 0; j < cpbmp2.Height; j++)
{
var c1 = cpbmp2.GetPixel(i, j);
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{
}
});
使用byte[]也會遇到同樣的問題
GetPixel效率問題
System.Drawing.Bitmap原生的GetPixel方法效率較低,可以使用C# Bitmap圖片GetPixel 和 SetPixel 效率問題中的寫法,經過測試,速度大概可以提高7倍。
測試代碼如下:
int times = 10;
//no. 2
System.Drawing.Bitmap bmp1 = new System.Drawing.Bitmap(file);
Stopwatch sw = new Stopwatch();
sw.Start();
for (int number = 0; number < times; number++)
for (int i = 0; i < bmp1.Width; i++)
for (int j = 0; j < bmp1.Height; j++)
{
var c1 = bmp1.GetPixel(i, j);
}
sw.Stop();
Console.WriteLine($"{nameof(Bitmap)}:{sw.ElapsedMilliseconds}");
//no. 1
OldLockBitmap oldLockBitmap = new OldLockBitmap(bmp1);
oldLockBitmap.LockBits();
sw.Restart();
for (int number = 0; number < times; number++)
for (int i = 0; i < bmp1.Width; i++)
for (int j = 0; j < bmp1.Height; j++)
{
var c1 = oldLockBitmap.GetPixel(i, j);
}
sw.Stop();
oldLockBitmap.UnlockBits();
Console.WriteLine($"{nameof(OldLockBitmap)}1:{sw.ElapsedMilliseconds}");
關於速率問題的討論:c# faster way of setting pixel colours