c# - 倾斜位图,RGB565 C#的步幅计算

标签 c# .net image-processing bitmap stride

我生成的一些图像是倾斜的,有些不是。

预期结果:(529x22)

enter image description here

实际结果:(529x22)

Don't mind the different image sizes, these are screenshots. They are both 529x22.

enter image description here

我正在使用的代码,是我刚刚从 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;
}

我很困惑,因为有些工作正常,没有倾斜。但其他人是倾斜的。我错过了什么?

更新

如评论和答案中所述,问题在于我如何计算步幅。我仍然对如何去做感到困惑,但我试过了:

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);
}

但结果是(更倾斜):

enter image description here

最佳答案

这似乎在这里工作:

private Bitmap ByteToImage(int w, int h, byte[] pixels)
{
    var bmp = new Bitmap(w, h, PixelFormat.Format16bppRgb565);
    byte bpp = 2;
    var BoundsRect = new Rectangle(0, 0, bmp.Width, bmp.Height);
    BitmapData bmpData = bmp.LockBits(BoundsRect,
                                    ImageLockMode.WriteOnly,
                                    bmp.PixelFormat);
    // copy line by line:
    for (int y = 0; y < h; y++ )
        Marshal.Copy(pixels, y * w * bpp, bmpData.Scan0 + bmpData.Stride * y, w * bpp);
    bmp.UnlockBits(bmpData);

    return bmp;
}

我使用循环将每一行数据放在正确的位置。数据不包括填充,但目标地址必须这样做。

因此我们需要将数据访问乘以实际的width * bytePerPixel,将目标地址乘以Stride ,即扫描线的长度,填充到下一个四字节的倍数。对于 width=300,它是 stride=300,对于 width=301,它是 stride=304..

一步移动所有像素数据只有在没有填充时才有效,即当宽度是 4 的倍数时。

关于c# - 倾斜位图,RGB565 C#的步幅计算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39046294/

相关文章:

c# - 如何停止 Designer 为用户控件上的公共(public)属性生成代码?

c# - 如何在 ASP.net 中使用 wkhtmltopdf.exe

c# - 在方法中更改结构

python - 使用 numpy 高效地将 16 位图像数据转换为 8 位显示,具有强度缩放

c++ - OpenCV 2.3 C++ 基础图像处理

c# - 使用 TempData 在 Controller 操作之间传递细节是不好的做法吗?

c# - 在 C# 中加速将复杂类型转换为另一种复杂类型以进行序列化

c# - 在 .NET 4.5 中找不到 HttpClient

c# - request.GetResponse 总是给出超时

java - 如何解压缩使用速记存储的图像?