无论颜色深度如何,图像都占用相同的字节数

时间:2017-04-16 08:43:23

标签: c# image-processing bitmap

下图显示了转换大小为1x2的24位彩色图像时会发生什么。

enter image description here

下图显示了转换大小为1x2的32位彩色图像时会发生什么。

enter image description here

我想,24位图像将占用6个字节。但是,两者都占用了8个字节。

结果,我的C#代码失败了。 Coz,它假设像素需要(ColorDepth/8)*Width*Height个字节数。

    public static int[,] ToInteger(Bitmap bitmap)
    {
        BitmapLocker locker = new BitmapLocker(bitmap);

        locker.Lock();

        byte[] data = locker.ImageData;
        int Width = locker.Width;
        int Height = locker.Height;
        int noOfBytesPerPixel = locker.BytesPerPixel;
        int[,] integerImage = new int[Width, Height];
        int byteCounter = 0;

        for (int i = 0; i < Width; i++)
        {
            for (int j = 0; j < Height; j++)
            {
                int integer = BitConverter.ToInt32(data, byteCounter);

                integerImage[i, j] = integer;

                byteCounter += noOfBytesPerPixel;
            }
        }

        locker.Unlock();

        return integerImage;
    }

那么,究竟发生了什么?

1 个答案:

答案 0 :(得分:1)

为什么图像占用相同的字节数?

我们无法确定,因为您没有显示您是如何获取它们的(默认情况下,它们可能会升级到32bpp,这是最快的处理,例如在WriteableBitmapEx中?)< / p>

计算每像素字节数的正确公式:

  

bytesPerPixel =(bitsPerPixel + 7)/ 8

以下是将8到32 bpp之间的任何内容转换为int的示例:

private static void DoWork(Bitmap bitmap)
{
    var width = bitmap.Width;
    var height = bitmap.Height;
    var rectangle = new Rectangle(0, 0, width, height);
    var data = bitmap.LockBits(rectangle, ImageLockMode.ReadOnly, bitmap.PixelFormat);

    var bitsPerPixel = GetBitsPerPixel(bitmap.PixelFormat);
    var bytesPerPixel = (bitsPerPixel + 7) / 8;
    var stride = data.Stride;
    var length = stride * data.Height;
    var pixels = new byte[length];
    Marshal.Copy(data.Scan0, pixels, 0, length);

    for (var y = 0; y < height; y++)
    for (var x = 0; x < width; x++)
    {
        var offset = y * stride + x * bytesPerPixel;
        var value = 0;
        for (var i = 0; i < bytesPerPixel; i++)
            value |= pixels[offset + i] << i;
    }
    bitmap.UnlockBits(data);
}

private static int GetBitsPerPixel(PixelFormat format)
{
    switch (format)
    {
        case PixelFormat.Format8bppIndexed:
            return 1;
        case PixelFormat.Format16bppRgb555:
            return 2;
        case PixelFormat.Format24bppRgb:
            return 24;
        case PixelFormat.Format32bppRgb:
            return 32;
        default: // TODO
            throw new NotSupportedException();
    }
}

(不确定有用性)

注意:我已经'仿效'了,因为我没有像你那样使用BitmapLocker课程。