我正在try 读取一个文件的字节.png图像使用File.ReadAllBytes(string)方法没有成功.

我的图像大小为2464x2056x3(15.197.952字节),但此方法返回的数组约为12.000.000字节.

我try 了一个同样大小的白色图像,得到了一个25.549的字节数组,判断字节数组,我可以看到所有类型的值,这显然是不正确的,因为这是一个白色图像.

我使用的代码是:

var frame = File.ReadAllBytes("C:\\workspace\\white.png");

我还try 先将图像作为图像对象打开,然后使用以下内容获取字节数组:

using (var ms = new MemoryStream())
{
  var imageIn = Image.FromFile("C:\\workspace\\white.png");
  imageIn.Save(ms, imageIn.RawFormat);
  var array = ms.ToArray();
}

但结果和以前一样...

知道发生了什么吗?

如何读取字节数组?

推荐答案

PNG is a compressed format.
See some info about it: Portable Network Graphics - Wikipedia.

这意味着二进制表示不是您期望的实际像素值.

你需要某种PNG解码器从压缩数据中获取像素值.

这篇帖子可能会 bootstrap 你走向正确的方向:Reading a PNG image file in .Net 2.0.请注意,这是非常古老的,也许有新的方法来做这件事.

另一方面:即使是像BMP这样的非压缩格式也有一个标题,所以你不能简单地读取二进制文件,并以一种简单的方式获取像素值.


Update:

using System.Drawing.Imaging;

byte[] GetPngPixels(string filename)
{
    byte[] rgbValues = null;

    // Load the png and convert to Bitmap. This will use a .NET PNG decoder:
    using (var imageIn = Image.FromFile(filename))
    using (var bmp = new Bitmap(imageIn))
    {
        // Lock the pixel data to gain low level access:
        BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat);

        // Get the address of the first line.
        IntPtr ptr = bmpData.Scan0;

        // Declare an array to hold the bytes of the bitmap.
        int bytes = Math.Abs(bmpData.Stride) * bmp.Height;
        rgbValues = new byte[bytes];

        // Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);

        // Unlock the pixel data:
        bmp.UnlockBits(bmpData);
    }

    // Here rgbValues is an array of the pixel values.
    return rgbValues;
}

This method will return a byte array with the size that you expect.
In order to use the data with opencv (or any similar usage), I advise you to enhance my code example and return also the image metadata (width, height, stride, pixel-format). You will need this metadata to construct a cv::Mat.

Csharp相关问答推荐

在命令行中使用时安装,但在单击时不会安装

属性getter和setter之间的空性不匹配?

如何在Visual Studio代码中更改大括号模式{},用于C#语言

dotnet集合中内部数组的局部变量副本的用途是什么?'

用C#调用由缓冲区指针参数组成的C API

从ASP.NET Core中的枚举字段填充 Select 选项时,将默认的第一个选项添加为 Select 元素

System.Net.Http.HttpClient.SendAsync(request)在docker容器内的POST方法30秒后停止

如何在实体框架中添加包含列表?

确定System.Text.Json序列化中是否无法识别Type

EF核心区分大小写的主键

在.NET 8最低API中从表单绑定中排除属性

为什么我不能从我的异步任务方法中返回异步任务方法?

在C#ASP.NET内核中使用INT AS-1进行控制器场景的单元测试

是否可以从IQueryable T中获取一个IdentyEntry T>

使用未赋值的、传递的局部变量

在同一个捕获中可以有多种类型的异常吗?

序列化过程中的死循环

无法向Unity注册Microsoft Logger

如何使用LINQ在C#中填充列表列表?

Unity 3D-意外轴捕捉和未知力对脉冲react 行为的影响