有人可以推荐一种更好的方法来检测位图是否具有Alpha通道以及它是否已被使用?这个方法适合我,但如果图像非常大,效率可能会很低,因为它在最坏的情况下循环所有像素:
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;
}
非常感谢
答案 0 :(得分:2)
你找不到比这更好的解决方案,我花了几个小时来优化:
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 (p = 3; p < Bytes.Length; p += 4) {
if (Bytes[p] != 255) return true;
}
return false;
}
答案 1 :(得分:1)
没试过这个,但想法是使用指针:
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;
}
}
答案 2 :(得分:1)
以下是基于你的例子。
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;
}