c#如何有效地读取字节数组中的像素数据

时间:2016-08-23 01:01:43

标签: c# image image-processing

我使用下面的代码将图像的像素数据读入byte []。这个解决方案适合我,但我需要优化,因为它需要更长的时间才有相同的其他解决方法。

private byte[] GetPixelBytes(string fileName)
{
    if (string.IsNullOrEmpty(fileName))
        throw new ArgumentException("FileName cal not be null or Blank");

    var bitmapImageSource = new BitmapImage(new System.Uri(fileName));
    System.Drawing.Bitmap imgo = new System.Drawing.Bitmap(fileName);
    var height = imgo.Height;
    var width = imgo.Width;

    //System.Drawing.Image.GetPixelFormatSize(imgo.PixelFormat);

    var bitsPerPixel = bitmapImageSource.Format.BitsPerPixel;
    var bytesPerPixel = (bitmapImageSource.Format.BitsPerPixel + 7) / 8;
    int size = (int)(bitmapImageSource.Width * bitmapImageSource.Height * bytesPerPixel);
    byte[] pixels = new byte[size];

    for (int i = 0; i < imgo.Width; i++)
    {
        for (int j = 0; j < imgo.Height; j++)
        {
            System.Drawing.Color pixel = imgo.GetPixel(i, j);
            //int offset = y * imgo.Width * 4 + x * 4;  (x is the column and y is the row)
            int offset = j * imgo.Width * bytesPerPixel + i * bytesPerPixel;
            switch (bytesPerPixel)
            {
                case 4:
                    pixels[offset + 0] = pixel.B;
                    pixels[offset + 1] = pixel.G;
                    pixels[offset + 2] = pixel.R;
                    pixels[offset + 3] = pixel.A;
                    break;
                case 3:
                    pixels[offset + 0] = pixel.B;
                    pixels[offset + 1] = pixel.G;
                    pixels[offset + 2] = pixel.R;
                    break;
                default:
                    throw new InvalidCastException("Only 32 and 24 BPP images are supported");
                    break;
            }
        }
    }
    return pixels;
}

我尝试过以下选项来优化

var bitmapData = imgo.LockBits(new System.Drawing.Rectangle(0,0,imgo.Width,imgo.Height),ImageLockMode.ReadOnly,imgo.PixelFormat);
var length = bitmapData.Stride * bitmapData.Height;
byte[] bytes = new byte[length];
System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, bytes, 0, length);
imgo.UnlockBits(bitmapData);

但在这种情况下,复制的字节包含的值与我原始函数的值不同。我正在使用具有以下属性的彩色图像。 Dimension: 3072*3072 Width: 3072 Pixel Height: 3072 Pixel Resolution: 96 dpi (Both) Bit depth: 24

已解决以下代码。

private byte[] ReadByte()
{
    System.Drawing.Bitmap imgo= new System.Drawing.Bitmap(filename);
    var bitmapData = imgo.LockBits(new System.Drawing.Rectangle(0,0,imgo.Width,imgo.Height),ImageLockMode.ReadOnly,imgo.PixelFormat);
    var length = bitmapData.Stride * bitmapData.Height;
    byte[] bytes = new byte[length];
    System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, bytes, 0, length);
    imgo.UnlockBits(bitmapData);
    return bytes;
}



private static BitmapSource ByteToImage(byte[] buffer, int width, int height, PixelFormat pixelFormat, string fileName, int bytesPerPixel = 0)
{
    var stride = ((width * pixelFormat.BitsPerPixel + 31) / 32) * 4;
    switch (bytesPerPixel)
    {
        case 1:
            pixelFormat = PixelFormats.Gray8;
            break;
        case 3:
            pixelFormat = PixelFormats.Rgb24;
            break;
        case 4:
            pixelFormat = PixelFormats.Bgr32;
            break;
    }
    var imago = new WriteableBitmap(width, height, 96, 96, pixelFormat, null);

    imago.WritePixels(new Int32Rect(0, 0, width, height), buffer, width * bytesPerPixel, 0);
    return imago;
}

0 个答案:

没有答案