在图片框中获取错误的数组大小到字节数组函数

Getting wrong array size in picturebox to byte array function

尝试将图片框转换为字节数组时,我得到错误的数组长度

PictureBox 是 352 * 288 = 101376 像素,转换为字节数组应该得到 101376 * 3 = 304128 字节的数组长度。我尝试使用以下函数转换为数组:

  private byte[] ImgToByteArray(Image img)
    {
        ImageConverter converter = new ImageConverter();
        return (byte[])converter.ConvertTo(img, typeof(byte[]));
    }

我这样调用函数:

 Byte[] LogImg = ImgToByteArray(LogPictureBox.Image);
 Int LogSize = LogImg.Length

LogSize的返回值=1070,我觉得奇怪,应该是304128。

我打断点看不懂,我验证了LogPictureBox.Image大小是352 * 288,那我哪里做错了?

我也试过使用内存流方法将图像复制到数组的函数,如下所示,但也导致了错误的大小

Public Function ImgToByteArray(ByVal img As Image) As Byte()
    Using mStream As New MemoryStream()
        img.Save(mStream, img.RawFormat)
        Return mStream.ToArray()
    End Using
End Function
// called this like
Byte[] LogImg=imgToByteArray((Bitmap)LogPictureBox.Image);

正如人们所说的颜色深度可能是问题所在,我将 LogPictureBox 编码为 24 位 p 像素,这等于 RGB,但仍然无法正常工作。另外值得一提的是,可以通过以下方式检索正确的数组大小 (304128):

Bitmap logBmp = (Bitmap)LogPictureBox.Image;
int logBmpW = logBmp.Width;
int logBmpH = logBmp.Height;
var lockedLog = logBmp.LockBits(new Rectangle(0, 0, logBmpW, logBmpH), System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
var logData = new int[lockedLog.Height * System.Math.Abs(lockedLog.Stride)];
// typical marshal code following bitmap to array etc still halted the code

我一直希望前两个函数能够工作,用于我想要进行的图像处理。因为我需要更新位图数组。我也一直在尝试其他方法,(上面是其中的一部分)但它也没有用。然后我似乎陷入了线程问题。也许这也是前面两个函数的问题。

我有一个网络摄像头触发了一个 newframe 事件,(Aforge 版本 2.2.4)它的这个事件不仅更新了它自己的图片框,而且还需要设置另一个日志图片框,显然线程在这里导致问题.

bytes/pixel的准确值不能这样计算

这取决于颜色深度。一个像素可以用一点来表示。 对于 256 色图像,每个像素需要一个字节。额外的深度需要更多的存储空间,高色每个像素使用 32 bits/4 字节。

我用你的代码测试了几个 Image size in 352x288 和 return 不同的值。 你可以用另一张相同尺寸的图片来测试我说的,请试试。

编辑: 也许你可以通过这段代码尝试不同的格式,然后检查长度,不同的文件类型也会有不同的结果:

 public byte[] imageToByteArray(System.Drawing.Image imageIn)
        {
            MemoryStream ms = new MemoryStream();
            imageIn.Save(ms, System.Drawing.Imaging.ImageFormat.Gif);
            return ms.ToArray();
        }

您尝试的代码不计算像素,无论其深度如何;它给出了原始格式的图像大小,包括 compression,包括 headers。所以在 DBMS 或磁盘

中确定您需要的 space 非常有用

如果要计算像素大小,需要三个数字:Height, Stridebpp:

int bpp = LogPictureBox.Image.PixelFormat == PixelFormat.Format24bppRgb ? 3 : 4;
int Stride = (LogPictureBox.Image.Width + 
             (LogPictureBox.Image.Width % (4 * (4 - (bpp / 8))) )) * bpp;
int LogSize = Stride * LogPictureBox.Image.Height;

请注意,bpp 代码非常 不完整 并假定 2432 位深度!

Stride是物理宽度,包括必要的填充。