2

我正在研究 ESC POS 打印机。使用下面的代码我可以打印图像,但问题是图像打印不正确。您可以在下图中看到。请查看我的代码并让我知道问题的确切位置。

- (void) btnPrintPicture{

UIImage * img = [UIImage imageNamed:@"download.png"];

int width = img.size.width;
int height = img.size.height;

unsigned char * binaryImageData = malloc(width * height);
unsigned char * data = malloc(height * (8 + width / 8));

unsigned char * grayData = [self convertImageToGray:img];

format_K_threshold(grayData, width, height, binaryImageData);
eachLinePixToCmd(binaryImageData, width, height, 0, data);

NSMutableArray *dataArray = [NSMutableArray new];
int splitBytes = 100;

NSData *comData = [[NSData alloc] initWithBytes:(const void *)data length:(height * (8+width/8))];

for(int i = 0;  i < comData.length ; i=i+splitBytes){

    NSData *subData = nil;

    if((i+splitBytes)>comData.length){
        subData = [comData subdataWithRange:NSMakeRange(i, (comData.length-i))];
    }else{
        subData = [comData subdataWithRange:NSMakeRange(i, splitBytes)];
    }

    [dataArray addObject:subData];
}

[dataArray enumerateObjectsUsingBlock:^(NSData  *obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [self.discoveredPeripheral writeValue:obj forCharacteristic:self.discoveredCharacteristic type:CBCharacteristicWriteWithResponse];
}];

free(grayData);
free(binaryImageData);
free(data);
}

此方法用于将图像转换为灰度。

-(unsigned char *)convertImageToGray:(UIImage *)i
{


   int kRed = 1;
    int kGreen = 2;
    int kBlue = 4;

int colors = kGreen | kBlue | kRed;
int m_width = i.size.width;
int m_height = i.size.height;

uint32_t *rgbImage = (uint32_t *) malloc(m_width * m_height * sizeof(uint32_t));
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(rgbImage, m_width, m_height, 8, m_width * 4, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaNoneSkipLast);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextSetShouldAntialias(context, NO);
CGContextDrawImage(context, CGRectMake(0, 0, m_width, m_height), [i CGImage]);
CGContextRelease(context);
CGColorSpaceRelease(colorSpace);

// now convert to grayscale
uint8_t *m_imageData = (uint8_t *) malloc(m_width * m_height);
for(int y = 0; y < m_height; y++) {
    for(int x = 0; x < m_width; x++) {
        uint32_t rgbPixel=rgbImage[y*m_width+x];
        uint32_t sum=0,count=0;
        if (colors & kRed) {sum += (rgbPixel>>24)&255; count++;}
        if (colors & kGreen) {sum += (rgbPixel>>16)&255; count++;}
        if (colors & kBlue) {sum += (rgbPixel>>8)&255; count++;}
        m_imageData[y*m_width+x]=sum/count;
    }
}
free(rgbImage);

return m_imageData;}


void format_K_threshold(unsigned char * orgpixels, int xsize, int ysize, unsigned char * despixels) {

int graytotal = 0;
int k = 0;

int i;
int j;
int gray;
for(i = 0; i < ysize; ++i) {
    for(j = 0; j < xsize; ++j) {
        gray = orgpixels[k] & 255;
        graytotal += gray;
        ++k;
    }
}

int grayave = graytotal / ysize / xsize;
k = 0;

for(i = 0; i < ysize; ++i) {
    for(j = 0; j < xsize; ++j) {
        gray = orgpixels[k] & 255;
        if(gray > grayave) {
            despixels[k] = 0;
        } else {
            despixels[k] = 1;
        }

        ++k;
    }
}
}

此方法是使用 ESC 命令打印图像。

void eachLinePixToCmd(unsigned char * src, int nWidth, int nHeight, int nMode, unsigned char * data) {


int p0[] = { 0, 0x80 };
int p1[] = { 0, 0x40 };
int p2[] = { 0, 0x20 };
int p3[] = { 0, 0x10 };
int p4[] = { 0, 0x08 };
int p5[] = { 0, 0x04 };
int p6[] = { 0, 0x02 };

int nBytesPerLine = nWidth / 8;

int offset = 0;
int k = 0;
for (int i = 0; i < nHeight; i++) {
    offset = i * (8 + nBytesPerLine);
    data[offset + 0] = 0x1d;
    data[offset + 1] = 0x76;
    data[offset + 2] = 0x30;
    data[offset + 3] = (unsigned char) (nMode & 0x01);
    data[offset + 4] = (unsigned char) (nBytesPerLine % 0xff);
    data[offset + 5] = (unsigned char) (nBytesPerLine / 0xff);
    data[offset + 6] = 0x01;
    data[offset + 7] = 0x00;
    for (int j = 0; j < nBytesPerLine; j++) {
        data[offset + 8 + j] = (unsigned char) (p0[src[k]] + p1[src[k + 1]] + p2[src[k + 2]] + p3[src[k + 3]] + p4[src[k + 4]] + p5[src[k + 5]] + p6[src[k + 6]] + src[k + 7]);
        k = k + 8;
    }
}
}

在此处输入图像描述

提前致谢。

4

1 回答 1

1

基于通过此更改在不同项目中修复了一个非常相似的错误,我猜测您的图像宽度不能被 8 整除。

nWidth % 8如果图像宽度不能被 8 整除,这条线将丢弃每一行上的像素,从而导致向右倾斜。

int nBytesPerLine = nWidth / 8;

相反,您应该用零填充:

int nBytesPerLine = (nWidth + 7) / 8;

您的data变量也需要增长以匹配,它有同样的问题。

最后,您正在GS v 0为每一行发出命令,这不是很有效。您可以为整个图像发出一次,并指定高度。来自同一个项目,这里有一个 C 示例。

于 2018-05-19T15:01:08.063 回答