You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从.NET 4.8迁移至.NET 8:1bpp Bitmap转ImageSharp的实现疑问

解决ImageSharp生成符合1bpp Bitmap Stride要求的字节数组问题

核心问题原因

原.NET System.Drawing.Bitmap 的1bpp格式Stride遵循4字节对齐规则,即每行字节数向上取整到4的倍数;而ImageSharp的Image<L8>直接输出的像素数据是连续无填充的,两者结构差异导致Zebra打印异常。

解决方案步骤

1. 计算与原Bitmap一致的Stride

先计算1bpp每行所需的最小字节数,再对齐到4字节边界:

private static int CalculateBitmapStride(int width)
{
    // 1bpp每行有效字节数:向上取整(宽度/8)
    int bytesPerRow = (width + 7) / 8;
    // 对齐到4字节边界,匹配System.Drawing.Bitmap的Stride规则
    return ((bytesPerRow + 3) / 4) * 4;
}

2. 转换Image为符合要求的字节数组

遍历每行像素,将L8格式转换为1bpp位数据,再添加0xFF填充字节到Stride长度:

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;

public static byte[] ConvertL8ToBitmap1BppBytes(Image<L8> image)
{
    int width = image.Width;
    int height = image.Height;
    int stride = CalculateBitmapStride(width);
    int effectiveBytesPerRow = (width + 7) / 8;
    byte[] outputBuffer = new byte[stride * height];

    for (int y = 0; y < height; y++)
    {
        int rowStart = y * stride;
        Span<L8> rowPixels = image.GetPixelRowSpan(y);
        byte[] rowData = new byte[effectiveBytesPerRow];

        // 将L8像素转换为1bpp位数据(匹配原Bitmap位顺序:字节最高位对应行最左侧像素)
        for (int x = 0; x < width; x++)
        {
            int byteIdx = x / 8;
            int bitIdx = 7 - (x % 8); // 从最高位开始填充
            bool isWhitePixel = rowPixels[x].PackedValue == 255;

            if (isWhitePixel)
            {
                rowData[byteIdx] |= (byte)(1 << bitIdx);
            }
            else
            {
                rowData[byteIdx] &= (byte)~(1 << bitIdx);
            }
        }

        // 复制有效数据到输出数组
        rowData.CopyTo(outputBuffer, rowStart);
        // 填充行尾对齐字节为0xFF(与原代码逻辑一致)
        for (int i = rowStart + effectiveBytesPerRow; i < rowStart + stride; i++)
        {
            outputBuffer[i] = 0xFF;
        }
    }

    return outputBuffer;
}

关键注意事项

  • 位顺序匹配:原Bitmap的1bpp格式中,每个字节的最高位对应行最左侧像素,转换时需按此规则填充位数据,否则会出现图像反转或错位。
  • 像素值映射:如果原Bitmap的1bpp定义与示例相反(如0代表白,1代表黑),需调整isWhitePixel的判断逻辑。
  • 行顺序一致性:ImageSharp的GetPixelRowSpan返回的是从上到下的行数据,与原BitmapData默认的TopDown顺序一致,无需额外反转。

内容的提问来源于stack exchange,提问作者Luis Abreu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 18:25:23