繁体   English   中英

获取位图的像素列的最佳,最快的方法是什么?

[英]What is the best and fast way to get pixels' column of bitmap?

从位图获取像素列的最快方法是什么? 我不考虑两个循环,因为这可能需要很长时间。 我将不胜感激。 谢谢!

我建议使用以下代码将位图转换为字节向量:

Bitmpa myImage=new Bitmap("myImage.bmp");    

BitmapData bmpData1=myImage.LockBits(new Rectangle(0,0,myImage.Width,myImage.Height), 
                 System.Drawing.Imaging.ImageLockMode.ReadWrite, myImage.PixelFormat);
byte[] myImageData = new byte[bmpData1.Stride * bmpData1.Height];
System.Runtime.InteropServices.Marshal.Copy(bmpData1.Scan0,myImageData,0
                       ,myImageData.Length);
myImgage.UnlockBits(bmpData1);

这样就可以轻松检索所需列上的像素。 只需遍历矢量myImageData ,步长等于每行像素数*每像素字节数。

只需注意每个像素用于表示位图的字节数即可。 这取决于PixelFormat

假设只需要一列,以下例程将对您有所帮助。

首先是使用可验证的C#代码的标准解决方案

static Color[] GetPixelColumn(Bitmap bmp, int x)
{
  Color[] pixelColumn = new Color[bmp.Height];
  for (int i = 0; i < bmp.Height; ++i)
  {
    pixelColumn[i] = bmp.GetPixel(x, i);
  }
  return pixelColumn;
}

这是一个更快的替代方法,但这要求您启用对C#编译器的unsafe支持

static Color[] GetPixelColumnFast(Bitmap bmp, int x)
{
  Color[] pixelColumn = new Color[bmp.Height];
  BitmapData pixelData = bmp.LockBits(
    new Rectangle(0, 0, bmp.Width, bmp.Height),
    ImageLockMode.ReadOnly,
    PixelFormat.Format32bppArgb);
  unsafe
  {
    int* pData = (int*)pixelData.Scan0.ToPointer();
    pData += x;
    for (int i = 0; i < bmp.Height; ++i)
    {
      pixelColumn[i] = Color.FromArgb(*pData);
      pData += bmp.Width;
    }
  }
  bmp.UnlockBits(pixelData);

  return pixelColumn;
}

这两个函数都将返回一个Color数组,其中包含位图中特定列的像素颜色。

将其转换为字节数组

    private static byte[, ,] BitmapToBytes(Bitmap bitmap)
    {
        BitmapData bitmapData = 
            bitmap.LockBits(new Rectangle(new Point(), bitmap.Size), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
        byte[] bitmapBytes;
        var stride = bitmapData.Stride;
        try
        {
            int byteCount = bitmapData.Stride * bitmap.Height;
            bitmapBytes = new byte[byteCount];
            Marshal.Copy(bitmapData.Scan0, bitmapBytes, 0, byteCount);
        }
        finally
        {
            bitmap.UnlockBits(bitmapData);                
        }
        byte[, ,] result = new byte[3, bitmap.Width, bitmap.Height];
        for (int k = 0; k < 3; k++)
        {
            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    result[k, i, j] = bitmapBytes[j * stride + i * 3 + k];
                }
            }
        }
        return result;
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM