Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何在.NET中检测位图是否具有Alpha通道_C#_.net_Image_Bitmap_Alpha - Fatal编程技术网

C# 如何在.NET中检测位图是否具有Alpha通道

C# 如何在.NET中检测位图是否具有Alpha通道,c#,.net,image,bitmap,alpha,C#,.net,Image,Bitmap,Alpha,有人可以推荐一种更好的方法来检测位图是否具有Alpha通道以及是否使用了它?这种方法对我来说很有效,但如果图像非常大,则可能效率低下,因为在最坏的情况下,它会循环所有像素: private static bool IsAlphaBitmap(Bitmap bmp, out BitmapData bmpData) { Rectangle bmpBounds = new Rectangle(0, 0, bmp.Width, bmp.Height); bmpData = bmp.Lo

有人可以推荐一种更好的方法来检测位图是否具有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;
}
private static bool IsAlphaBitmap(位图bmp,out位图数据bmpData)
{
矩形bmpBounds=新矩形(0,0,bmp.Width,bmp.Height);
bmpData=bmp.LockBits(bmpBounds,ImageLockMode.ReadOnly,bmp.PixelFormat);
尝试
{

for(int y=0;y没有尝试此方法,但其思想是使用指针:

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;
   }
}
不安全
{
字节*ptrAlpha=((字节*)bmpData.Scan0.ToPointer())+3;
对于(int i=bmpData.Width*bmpData.Height;i>0;--i)//前缀--应该更快
{
如果(*ptrAlpha<255)
返回true;
ptrAlpha+=4;
}
}

没有尝试此方法,但其想法是使用指针:

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;
   }
}
不安全
{
字节*ptrAlpha=((字节*)bmpData.Scan0.ToPointer())+3;
对于(int i=bmpData.Width*bmpData.Height;i>0;--i)//前缀--应该更快
{
如果(*ptrAlpha<255)
返回true;
ptrAlpha+=4;
}
}

以下是基于您的示例

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;
}
private static bool IsAlphaBitmap(位图bmp,out位图数据bmpData)
{
var bmpBounds=新矩形(0,0,bmp.Width,bmp.Height);
bmpData=bmp.LockBits(bmpBounds,ImageLockMode.ReadOnly,bmp.PixelFormat);
尝试
{
var rowDataLength=bmpData.Width*4;//用于32ARGB位图
var buffer=新字节[rowDataLength];
对于(变量y=0;y0&&buffer[p]<255)
返回true;
}
}
}
最后
{
bmp.UnlockBits(bmpData);
}
返回false;
}

以下是基于您的示例

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;
}
private static bool IsAlphaBitmap(位图bmp,out位图数据bmpData)
{
var bmpBounds=新矩形(0,0,bmp.Width,bmp.Height);
bmpData=bmp.LockBits(bmpBounds,ImageLockMode.ReadOnly,bmp.PixelFormat);
尝试
{
var rowDataLength=bmpData.Width*4;//用于32ARGB位图
var buffer=新字节[rowDataLength];
对于(变量y=0;y0&&buffer[p]<255)
返回true;
}
}
}
最后
{
bmp.UnlockBits(bmpData);
}
返回false;
}

您找不到比这更好的解决方案,我花了几个小时优化:

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;
}
public bool IsAlphaBitmap(参考System.Drawing.Imaging.bitmap数据BmpData)
{
字节[]字节=新字节[BmpData.Height*BmpData.Stride];
Marshal.Copy(BmpData.Scan0,Bytes,0,Bytes.Length);
对于(p=3;p
您找不到比这更好的解决方案,我花了几个小时优化:

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;
}
public bool IsAlphaBitmap(参考System.Drawing.Imaging.bitmap数据BmpData)
{
字节[]字节=新字节[BmpData.Height*BmpData.Stride];
Marshal.Copy(BmpData.Scan0,Bytes,0,Bytes.Length);
对于(p=3;p
你试过Image.isalphapixelformatal似乎你的问题在StackOverflow上已经解决了:@Digvijay:IsAlphaPixelFormat对我不起作用,因为我不仅需要在位图有alpha通道的情况下,还需要在位图使用alpha通道的情况下使用它。@Digvijay:你提供的链接也会循环所有像素。我要问的是是否存在e任何其他不循环像素的解决方案。谢谢,您不需要将int32值转换为颜色,所以只需对每个Y进行扫描线,并循环所有Alpha字节(稍微修改vulkanino建议的内容)。你试过Image.IsAlphaPixelFormatAlso看起来你的问题在StackOverflow上已经解决了:@Digvijay:IsAlphaPixelFormat对我不起作用,因为我需要的不仅仅是位图是否有alpha通道,还有位图是否被使用。@Digvijay:你提供的链接也会循环所有像素。我想问的是是否有任何像素另一种解决方案是不循环像素。谢谢你不需要将int32值转换为颜色,所以只需对每个Y进行扫描线,并循环所有Alpha字节(稍微修改vulkanino的建议)。在我的公司不可能编译不安全的,抱歉,所以这个答案对我无效,最好执行ani API调用。在我的公司不可能编译不安全的,抱歉,所以这个答案对我无效,最好执行ani API调用。我不是位图操作专家,但如果BmpDat,这将引发异常a、 Stride属性的值为负值。我尝试了使用16x16的本机hBitmaps和alpha通道的代码,该代码是通过调用IShellItemImageFactory.GetImage()获得的,stride为-64。另一方面,这个解决方案对我来说非常适合:我不是位图操作专家,但如果BmpData.stride属性的值为负值,这将引发异常。我已经使用16x16的本机hBitmaps和alpha通道尝试了该代码,我通过调用IShellItemImageFactory.GetImage()获得了该代码,stride为-64。另一方面,这个解决方案对我来说非常适合: