C#中将光栅格式字节数组转列格式的优化方案求助
优化Raster到ESC/POS Column格式的字节级转换方案
确实,直接用BitArray做位操作会带来不必要的内存开销和性能损耗,尤其是处理较大图像时。我们可以通过直接操作字节和位来实现更高效的转换,完全规避中间的BitArray转换步骤。
先明确两种格式的核心差异
- Raster格式(输入):按行存储,每行的像素每8个打包成一个字节,字节内的位顺序是左→右对应7→0位(比如一行最左边的像素是当前字节的第7位,最右边是第0位)。
- Column格式(输出):按列存储,每列的像素每8个打包成一个字节,字节内的位顺序是上→下对应7→0位(比如一列最上面的像素是当前字节的第7位,最下面是第0位)。
优化后的字节级实现代码
private byte[] ConvertRasterToColumnFormat(byte[] rasterData, int width, int height) { // 补全宽高到8的倍数(ESC/POS列打印要求) var finalHeight = ((height + 7) / 8) * 8; var finalWidth = ((width + 7) / 8) * 8; // 结果数组总长度:(最终宽 * 最终高) / 8 位 → 转成字节数 var result = new byte[(finalWidth * finalHeight) / 8]; // 遍历每个原始像素的坐标 for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { // 1. 计算该像素在原始Raster数据中的字节索引和位位置 // 原始行内的字节索引:x / 8;行偏移:y * (finalWidth / 8) int rasterByteIndex = y * (finalWidth / 8) + (x / 8); // 原始字节内的位:左→右对应7→0位,所以是7 - (x % 8) int rasterBitPos = 7 - (x % 8); // 提取该位的值 bool bitValue = (rasterData[rasterByteIndex] & (1 << rasterBitPos)) != 0; // 2. 计算该像素在目标Column数据中的字节索引和位位置 // 目标列内的字节索引:y / 8;列偏移:x * (finalHeight / 8) int columnByteIndex = x * (finalHeight / 8) + (y / 8); // 目标字节内的位:上→下对应7→0位,所以是7 - (y % 8) int columnBitPos = 7 - (y % 8); // 3. 将位值设置到目标字节的对应位置 if (bitValue) { result[columnByteIndex] |= (byte)(1 << columnBitPos); } // 注意:未覆盖的位置(补全的宽高区域)默认是0,符合ESC/POS要求 } } return result; }
为什么这个方案更优?
- 减少内存开销:不需要创建两个
BitArray对象,直接操作原始字节数组和结果数组,内存占用更低。 - 提升执行效率:避免了
BitArray内部的位到字节的转换逻辑,以及最终的CopyTo操作,所有计算都是直接的算术运算和位操作,速度更快。 - 逻辑更直观:直接映射每个像素的原始位置和目标位置,代码可读性更强,便于维护和调试。
验证说明
你可以用之前的测试案例对比新旧方案的输出结果,确保转换逻辑一致。对于大尺寸图像,这个方案的性能提升会更明显——比如处理分辨率较高的小票图像时,字节级操作的速度可能是BitArray方案的数倍。
内容的提问来源于stack exchange,提问作者YZahringer
相关产品推荐
相关产品推荐

