This is the method im using today:
public static Bitmap CloudsOnly(Bitmap bitmapwithclouds, Bitmap bitmapwithoutclouds)
{
Color color;
Color backgroundColor = Color.Black;
CreateErrorsArray(bitmapwithclouds, bitmapwithoutclouds);
int tolerance = tolerancenum * tolerancenumeric + tolerancenumeric * tolerancenumeric + tolerancenumeric * tolerancenumeric;
Bitmap newbitmap = new Bitmap(512, 512);
for (int x = 0; x < bitmapwithclouds.Width; x++)
{
for (int y = 0; y < bitmapwithclouds.Height; y++)
{
int error = errorsArray[x, y];
if (error < tolerance)
{
color = backgroundColor;
}
else
{
color = bitmapwithclouds.GetPixel(x, y);
}
newbitmap.SetPixel(x, y, color);
}
}
newbitmap.Save(@"d:\test\newbitmap.jpg");
return newbitmap;
}
But GetPixel is slow i searched google and found some methods using LockBits for example this method:
private bool CompareBitmaps(Image left, Image right)
{
if (object.Equals(left, right))
return true;
if (left == null || right == null)
return false;
if (!left.Size.Equals(right.Size) || !left.PixelFormat.Equals(right.PixelFormat))
return false;
Bitmap leftBitmap = left as Bitmap;
Bitmap rightBitmap = right as Bitmap;
if (leftBitmap == null || rightBitmap == null)
return true;
#region Optimized code for performance
int bytes = left.Width * left.Height * (Image.GetPixelFormatSize(left.PixelFormat) / 8);
bool result = true;
byte[] b1bytes = new byte[bytes];
byte[] b2bytes = new byte[bytes];
BitmapData bmd1 = leftBitmap.LockBits(new Rectangle(0, 0, leftBitmap.Width - 1, leftBitmap.Height - 1), ImageLockMode.ReadOnly, leftBitmap.PixelFormat);
BitmapData bmd2 = rightBitmap.LockBits(new Rectangle(0, 0, rightBitmap.Width - 1, rightBitmap.Height - 1), ImageLockMode.ReadOnly, rightBitmap.PixelFormat);
Marshal.Copy(bmd1.Scan0, b1bytes, 0, bytes);
Marshal.Copy(bmd2.Scan0, b2bytes, 0, bytes);
for (int n = 0; n <= bytes - 1; n++)
{
if (b1bytes[n] != b2bytes[n])
{
result = false;
break;
}
}
leftBitmap.UnlockBits(bmd1);
rightBitmap.UnlockBits(bmd2);
#endregion
return result;
}
But this one just tell me if one image is the same like the second one. I want to use my method above but with LockBits or some way faster.
How can i change my method the first one above to be faster ?
GetPixel is terrible slow, don't use it if you have more than one pixel and you don't want to spend your childhood by watching your code crawling through a picture.
You have to use unsafe code (unmanaged) for fast accessing of picture. See this post for help: C# Bitmap using unsafe code
Performance comparison: C# Image Processing Performance - Unsafe vs. Safe code, Part II
I can recommend one naive optimization. Instead of manualy comparing each byte in resulting array you can use hash funciton. It means that next code:
for (int n = 0; n <= bytes - 1; n++)
{
if (b1bytes[n] != b2bytes[n])
{
result = false;
break;
}
}
can be replaced with
var sha1 = new SHA1CryptoServiceProvider();
return sha1.ComputeHash(b1bytes) == sha1.ComputeHash(b2bytes);
Build in hash functions are well optimized.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.