Csharp/C#教程:如何从具有负步幅的位图复制像素数据?分享


如何从具有负步幅的位图复制像素数据?

我一直在寻找将Bitmap转换为8bpp的最快方法。 我发现了两种方法:

1。

public static System.Drawing.Image ConvertTo8bpp(Bitmap oldbmp) { using (var ms = new MemoryStream()) { oldbmp.Save(ms, ImageFormat.Gif); ms.Position = 0; return System.Drawing.Image.FromStream(ms); } } 

2. https://www.wischik.com/lu/programmer/1bpp.html

但是: 1。结果质量很差(托盘坏)

2给我一个负步幅的位图,当我尝试锁定位并将数据复制到字节数组时,我得到一个exception: 尝试读取或写入受保护的内存。 这通常表明其他内存已损坏。

  BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, bmp.PixelFormat); this.stride = bmpData.Stride; this.bytesPerPixel = GetBytesPerPixel(bmp.PixelFormat); int length = bmpData.Stride * bmp.Height; if (this.stride < 0) this.data = new byte[-length]; else this.data = new byte[length]; Marshal.Copy(bmpData.Scan0, data, 0, length); //Unlock the bitmap bmp.UnlockBits(bmpData); 

我怎样才能让2给出积极的进步? 或者我如何使用负步幅的锁定位来复制数据?

一次复制1行,将行的起始指针计算为((byte*)scan0 + (y * stride)) 。 对于正向或反向步幅,代码将是相同的。

这里的问题是Scan0指向第一条扫描线的开头,而不是第一个数据字节的开头。 在自下而上的位图中,第一个扫描线是位图数据末尾的Stride字节。

当您调用Marshal.CopyScan0复制数据时,它会尝试从位置((Height-1)*Stride)开始复制(Height*Stride)字节。 显然,这将会流入杂草。

如果您只想复制位图数据,则必须使用Scan0 - (Height-1)*Stride计算起始地址。 这将从位图数据的开头开始。 您可以将该计算地址传递给Marshal.Copy

如果要按顺序复制扫描线(即顶部,下一个,下一个,……底部),则必须一次复制一行:从Scan0复制Stride字节,然后添加Stride (负数),复制那条线等Rick Brewster在那里有正确的答案: https : //stackoverflow.com/a/10360753/56778

我不知道为什么FromHbitmap方法创建的Bitmap有些奇怪,但我知道你可以通过使用Bitmap bmpClone = (Bitmap)bmp.Clone();来修复它Bitmap bmpClone = (Bitmap)bmp.Clone(); 并在bmpClone上执行LockBits。

另外,我发现如果使用bmp.Clone() ,则在完成克隆之前不能对bmp进行Dispose()。

这也有效,让你尽快处理负步幅图像:

  Bitmap bmp = null; using (Bitmap bmpT = CopyToBpp(bmpO, 1)) { bmp = new Bitmap(bmpT); } 

来自BitmapData上的C#文档:步幅是单行像素(扫描线)的宽度,四舍五入到四字节边界。 如果步幅为正,则位图为自上而下。 如果步幅为负,则位图自下而上

我猜你得到的例外是由于

 this.data = new byte[-length]; 

然后尝试将数据复制到负大小的字节数组中(我看不出它甚至是如何编译的……)。

上述就是C#学习教程:如何从具有负步幅的位图复制像素数据?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!

本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

ctvol管理联系方式QQ:251552304

本文章地址:https://www.ctvol.com/cdevelopment/1015457.html

(0)
上一篇 2021年12月30日
下一篇 2021年12月30日

精彩推荐