Reputation: 31857
Someone could recommend a better way to detect if a bitmap has Alpha channel and if it's used? This method works for me, but could be inefficient if the image is very large, because it loops all the pixels in the worst case:
private static bool IsAlphaBitmap(Bitmap bmp, out BitmapData bmpData)
{
Rectangle bmpBounds = new Rectangle(0, 0, bmp.Width, bmp.Height);
bmpData = bmp.LockBits(bmpBounds, ImageLockMode.ReadOnly, bmp.PixelFormat);
try
{
for (int y = 0; y <= bmpData.Height - 1; y++)
{
for (int x = 0; x <= bmpData.Width - 1; x++)
{
Color pixelColor = Color.FromArgb(
Marshal.ReadInt32(
bmpData.Scan0, (bmpData.Stride * y) + (4 * x)));
if (pixelColor.A > 0 & pixelColor.A < 255)
{
return true;
}
}
}
}
finally
{
bmp.UnlockBits(bmpData);
}
return false;
}
Thank you very much
Upvotes: 0
Views: 2923
Reputation: 6471
You won't find a solution better than this, it took me hours to optimize:
public bool IsAlphaBitmap(ref System.Drawing.Imaging.BitmapData BmpData)
{
byte[] Bytes = new byte[BmpData.Height * BmpData.Stride];
Marshal.Copy(BmpData.Scan0, Bytes, 0, Bytes.Length);
for (var p = 3; p < Bytes.Length; p += 4) {
if (Bytes[p] != 255) return true;
}
return false;
}
Upvotes: 2
Reputation: 1222
Here's the example based on yours.
private static bool IsAlphaBitmap(Bitmap bmp, out BitmapData bmpData)
{
var bmpBounds = new Rectangle(0, 0, bmp.Width, bmp.Height);
bmpData = bmp.LockBits(bmpBounds, ImageLockMode.ReadOnly, bmp.PixelFormat);
try
{
var rowDataLength = bmpData.Width * 4; // for 32ARGB bitmap
var buffer = new byte[rowDataLength];
for (var y = 0; y < bmpData.Height; y++)
{
Marshal.Copy((IntPtr) ((int)bmpData.Scan0 + bmpData.Stride*y), buffer, 0, rowDataLength);
for (int p = 0; p < rowDataLength; p += 4)
{
if (buffer[p] > 0 && buffer[p] < 255)
return true;
}
}
}
finally
{
bmp.UnlockBits(bmpData);
}
return false;
}
Upvotes: 1
Reputation: 9134
Didn't try this, but the idea is to work with pointers:
unsafe
{
byte* ptrAlpha = ((byte*)bmpData.Scan0.ToPointer()) + 3;
for (int i = bmpData.Width * bmpData.Height; i > 0; --i) // prefix-- should be faster
{
if ( *ptrAlpha < 255 )
return true;
ptrAlpha += 4;
}
}
Upvotes: 1