将RAW字节数据转换为Bitmap

时间:2016-10-07 06:23:04

标签: c# android image-processing bitmap

我正在使用ADB截取Android设备的屏幕截图,并将屏幕截图作为原始字节数据接收。

我知道通过的原始字节数据格式为rgba

红色偏移0,绿色偏移8,蓝色偏移16,Alpha偏移24,每个值为1个字节。这构成了整个字节数组。

我正在尝试将此字节数组转换为C#中的位图,并且它在大多数情况下工作,图像在各方面看起来都是正确的,除了它通过蓝色色调&# 39; - 着色已关闭。

以下是我用来转换原始字节数据的代码:

int WriteBitmapFile(string filename, int width, int height, byte[] imageData)
    {
        using (var stream = new MemoryStream(imageData))
        using (var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0,
                                                            bmp.Width,
                                                            bmp.Height),
                                              ImageLockMode.WriteOnly,
                                              bmp.PixelFormat);
            IntPtr pNative = bmpData.Scan0;

            Marshal.Copy(imageData, 0, pNative, imageData.Length);

            bmp.UnlockBits(bmpData);

            bmp.Save(filename);
        }

        return 1;
    }

我在this post中读到它可能与实际rgba值的字节顺序有关。正如你在上面的代码中看到的那样,我尝试将我的bmpData.Scan0转换为int *,它仍然以蓝色色调出现。

我现在正在捣乱我的大脑,我现在可以做些什么来让这个图像通过正确的颜色来实现。我假设它的红色为蓝色,蓝色为红色,反之亦然。

我认为我可以操作原始字节数据,以便在将其转换为位图时按正确的字节顺序排列,但是我不知道如何才能这样做。

有什么建议吗?

2 个答案:

答案 0 :(得分:5)

所以,最后我的解决方案很简单。

int WriteBitmapFile(string filename, int width, int height, byte[] imageData)
    {
        byte[] newData = new byte[imageData.Length];

        for(int x = 0; x < imageData.Length; x+= 4)
        {
            byte[] pixel = new byte[4];
            Array.Copy(imageData, x, pixel, 0, 4);

            byte r = pixel[0];
            byte g = pixel[1];
            byte b = pixel[2];
            byte a = pixel[3];

            byte[] newPixel = new byte[] { b, g, r, a };

            Array.Copy(newPixel, 0, newData, x, 4);
        }

        imageData = newData;

        using (var stream = new MemoryStream(imageData))
        using (var bmp = new Bitmap(width, height, PixelFormat.Format32bppArgb))
        {
            BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0,
                                                            bmp.Width,
                                                            bmp.Height),
                                              ImageLockMode.WriteOnly,
                                              bmp.PixelFormat);

            IntPtr pNative = bmpData.Scan0;
            Marshal.Copy(imageData, 0, pNative, imageData.Length);

            bmp.UnlockBits(bmpData);

            bmp.Save(filename);
        }

        return 1;
    }

我所要做的就是循环遍历imageData并调整构成像素的字节并重新排序,以便它们适合Windows位图的预期格式,即BGRA。

显然,我仍然可以在for循环中做一些小的优化来改变字节,但是它正在工作。

答案 1 :(得分:0)

你看过这个post了吗? 您已经说明了每一个价值观&#39;是8个字节,所以1个像素是4x8 = 32个字节?但是你使用32bpp图像格式,因此每像素32位 - &gt; 1个像素= 4个字节。

如果你从另一个处理器/网络/ ...获取图像,也要注意小/大端,