如何从字节数组创建位图?

goG*_*Gud 56 c# image bytearray bitmap

我搜索了关于字节数组的所有问题,但我总是失败.我从未编写过c#我是这方面的新手.你能帮我解决一下如何从字节数组制作图像文件.

这是我的函数,它将字节存储在名为的数组中 imageData

public void imageReady( byte[] imageData, int fWidth, int fHeight))
Run Code Online (Sandbox Code Playgroud)

Mik*_*oud 99

你需要把它们bytes变成MemoryStream:

Bitmap bmp;
using (var ms = new MemoryStream(imageData))
{
    bmp = new Bitmap(ms);
}
Run Code Online (Sandbox Code Playgroud)

那使用Bitmap(Stream stream)构造函数重载.

更新:请记住,根据文档和我一直在阅读的源代码,ArgumentException将会抛出以下条件:

stream does not contain image data or is null.
-or-
stream contains a PNG image file with a single dimension greater than 65,535 pixels.
Run Code Online (Sandbox Code Playgroud)

  • 没有!不要丢弃流!来自[`Bitmap(Stream)`](https://msdn.microsoft.com/en-us/library/z7ha67kw%28v=vs.110%29.aspx):"你必须让流保持打开状态位图." (8认同)
  • 我收到与 @mario 的答案相同的错误消息: System.Drawing.dll 中出现类型为“System.ArgumentException”的未处理异常附加信息:参数无效 (4认同)
  • 正如@piedar 所指出的,在位图被处置之前,不应关闭/处置流。但是,如果您使用的是`MemoryStream`,那么您不必担心关闭它,因为无论如何,`MemoryStream` 在被释放时实际上并没有做任何事情。[`System.Drawing.ImageConverter.ConvertFrom`](http://referencesource.microsoft.com/#q=ImageConverter) 方法实际上利用了这一事实,因此做出这种假设似乎是安全的。做,只需`var bmp = new Bitmap(new MemoryStream(imageData));` 就足够了。 (2认同)

goG*_*Gud 23

伙计们,感谢您的帮助.我认为所有这些答案都有效.但是我认为我的字节数组包含原始字节.这就是为什么所有这些解决方案都不能用于我的代码.

但是我找到了解决方案.也许这个解决方案可以帮助其他有问题的编码员.

static byte[] PadLines(byte[] bytes, int rows, int columns) {
   int currentStride = columns; // 3
   int newStride = columns;  // 4
   byte[] newBytes = new byte[newStride * rows];
   for (int i = 0; i < rows; i++)
       Buffer.BlockCopy(bytes, currentStride * i, newBytes, newStride * i, currentStride);
   return newBytes;
 }

 int columns = imageWidth;
 int rows = imageHeight;
 int stride = columns;
 byte[] newbytes = PadLines(imageData, rows, columns);

 Bitmap im = new Bitmap(columns, rows, stride, 
          PixelFormat.Format8bppIndexed, 
          Marshal.UnsafeAddrOfPinnedArrayElement(newbytes, 0));

 im.Save("C:\\Users\\musa\\Documents\\Hobby\\image21.bmp");
Run Code Online (Sandbox Code Playgroud)

此解决方案适用于8位256 bpp(Format8bppIndexed).如果您的图像有其​​他格式,则应更改PixelFormat.

现在颜色有问题.一旦我解决了这个问题,我就会为其他用户编辑我的答案.

*PS =我不确定步幅值,但对于8位,它应该等于列.

此功能也适用于我..此功能将8位灰度图像复制为32位布局.

public void SaveBitmap(string fileName, int width, int height, byte[] imageData)
        {

            byte[] data = new byte[width * height * 4];

            int o = 0;

            for (int i = 0; i < width * height; i++)
            {
                byte value = imageData[i];


                data[o++] = value;
                data[o++] = value;
                data[o++] = value;
                data[o++] = 0; 
            }

            unsafe
            {
                fixed (byte* ptr = data)
                {

                    using (Bitmap image = new Bitmap(width, height, width * 4,
                                PixelFormat.Format32bppRgb, new IntPtr(ptr)))
                    {

                        image.Save(Path.ChangeExtension(fileName, ".jpg"));
                    }
                }
            }
        }
Run Code Online (Sandbox Code Playgroud)

  • 嗨goGud.您不需要填充数据,"Format32bppRgb"每个像素使用4个字节(或者每个像素32位,如名称所示,8位== 1个字节)."Format32bppRgb"实际上是RGBX,而您的数据似乎存储为"RGB",因此每像素3个字节尝试Format24bppRGB,这将是每个像素3个字节.并且你的步幅将是宽度*3,最后值得一提的是IntPtr部分,你必须保持单独的引用...如果你想要位图持久,我建议看看这篇文章:http:// stackoverflow. COM /问题/ 6782489 /像素创建位图从 - 一个字节阵列-的-数据 (4认同)

Mar*_*num 15

可以这么简单:

var ms = new MemoryStream(imageData);
System.Drawing.Image image = Image.FromStream(ms);

image.Save("c:\\image.jpg");
Run Code Online (Sandbox Code Playgroud)

测试出来:

byte[] imageData;

// Create the byte array.
var originalImage = Image.FromFile(@"C:\original.jpg");
using (var ms = new MemoryStream())
{
    originalImage.Save(ms, ImageFormat.Jpeg);
    imageData = ms.ToArray();
}

// Convert back to image.
using (var ms = new MemoryStream(imageData))
{
    Image image = Image.FromStream(ms);
    image.Save(@"C:\newImage.jpg");
}
Run Code Online (Sandbox Code Playgroud)

  • 这里的问题是它不是所讨论的原始 RGB 流。为了检索没有给出尺寸的数据,它保存图像,就像可以保存任何对象一样,其中对象本身已经是带有化妆的图像(ea尺寸像素格式等)。 (2认同)

Maj*_*man 7

此外,您可以简单地转换byte arrayBitmap.

var bmp = new Bitmap(new MemoryStream(imgByte));
Run Code Online (Sandbox Code Playgroud)

也可以直接Bitmap文件路径获取。

Bitmap bmp = new Bitmap(Image.FromFile(filePath));
Run Code Online (Sandbox Code Playgroud)