【发布时间】:2016-08-19 19:18:10
【问题描述】:
我生成的一些图像是倾斜的,有些则不是。
预期结果:(529x22)
实际结果:(529x22)
不要介意不同的图像尺寸,这些是屏幕截图。它们都是 529x22。
我正在使用的代码,我刚刚从 SO 的一个问题的答案中得到这个。
// some other method
byte[] pixels = new byte[size - 16];
Array.Copy(this.data, offset, pixels, 0, pixels.Length);
this.ByteToImage(w, h, pixels);
// builds the pixels to a image
private Bitmap ByteToImage(int w, int h, byte[] pixels)
{
var bmp = new Bitmap(w, h, PixelFormat.Format16bppRgb565);
var BoundsRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
BitmapData bmpData = bmp.LockBits(BoundsRect,
ImageLockMode.WriteOnly,
bmp.PixelFormat);
// bytes => not using this because it gives error
// eg. pixel.Length = 16032, bytes = 16064
int bytes = bmpData.Stride * bmp.Height;
Marshal.Copy(pixels, 0, bmpData.Scan0, pixels.Length);
bmp.UnlockBits(bmpData);
return bmp;
}
我很困惑,因为有些工作正常,而不是倾斜。但其他人是倾斜的。我错过了什么?
更新
如 cmets 和答案中所述,问题在于我如何计算步幅。我仍然对如何做到这一点感到困惑,但我尝试了这个:
public static void RemovePadding(this Bitmap bitmap)
{
int bytesPerPixel = Image.GetPixelFormatSize(bitmap.PixelFormat) / 8;
BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
var pixels = new byte[bitmapData.Width * bitmapData.Height * bytesPerPixel];
for (int row = 0; row < bitmapData.Height; row++)
{
var dataBeginPointer = IntPtr.Add(bitmapData.Scan0, row * bitmapData.Stride);
Marshal.Copy(dataBeginPointer, pixels, row * bitmapData.Width * bytesPerPixel, bitmapData.Width * bytesPerPixel);
}
Marshal.Copy(pixels, 0, bitmapData.Scan0, pixels.Length);
bitmap.UnlockBits(bitmapData);
}
但结果是(更倾斜):
【问题讨论】:
-
您显然有步幅问题。如果您需要帮助解决您的错误,请发布一个带有良好minimal reproducible example 的问题,该问题可以可靠地重现问题,并更具体地说明运行代码时发生的错误(如果有)。您可能只是错误地计算了步幅;某些图像之所以有效,是因为它们的宽度与您的错误计算兼容(Windows 位图格式中的步幅四舍五入到最接近的 32 位......也许它只有 16 位,我不记得肯定是在我的头顶上)。
-
对不起,我不知道它叫什么。位图新手。我会尝试解决这个问题。
-
@TaW 4 个字节?填充?
-
是或者更确切地说:扫描线被填充到下一个四字节的倍数,即stride比净像素线长0-3个字节。
-
您不必计算Stride也不必移除padding,系统会计算Stride并插入padding。您一次性移动未填充数据的方式很可能是错误。越过线的循环似乎更有可能起作用。
标签: c# .net image-processing bitmap stride