在picturebox中获取错误的数组大小到字节数组函数

时间:2015-03-05 11:02:36

标签: c# arrays multithreading picturebox

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

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位像素,等于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

我一直希望前两个功能能够正常工作,因为我想做的图像操作。因为我需要更新位图数组。 我也在尝试其他方法,(上面就是其中的一部分),但它也没有用。然后我进入线程问题接缝。 也许这是早期2的功能问题。

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

2 个答案:

答案 0 :(得分:0)

字节/像素的准确值无法像那样计算。

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

我测试了几个Image size in 352x288并使用您的代码返回不同的值。 您可以使用相同尺寸的其他图像来测试我说的内容,请尝试。

修改 也许您可以通过此代码尝试不同的格式,然后检查长度,不同的文件类型也会有不同的后果:

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

答案 1 :(得分:0)

你尝试的代码不计算像素,无论它们的深度如何;它以正版格式显示图像的大小,包括压缩,包括标题。因此,在DBMS或磁盘

中确定所需的空间非常有用

如果您想计算像素大小,则需要三个数字: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是物理宽度,包括必要的填充。