使用“光栅模式”直接打印到以太网打印机:需要基本指导

我偶然发现了一个超出我的专业领域的问题,而且我没有导师可以求助于此。

我有一个收据打印机,我需要通过iOS应用程序进行交互。 打印机与设备位于同一网络上,因此我可以通过支持的“线路模式命令”来解决它

我想做的是保持我已经跨平台工作的代码 – 即它是一个UIView / NSView,如果你不熟悉OS X / iOS,它只是一个标准的vanilla视图,我可以渲染成PDF / PNG格式。 值得庆幸的是,打印机具有“光栅图形”模式,这似乎是我需要的。

不幸的是,无论是命令规范的破坏英语,还是我对基本C以外的任何东西的完全缺乏了解,或者我完全缺乏关于图形的知识,我都不知道如何从我拥有的命令规范开始。 我知道打印机和我的网络工作,因为我可以通过网络解决它并发送基本的feed命令。 但是,我不知道如何从PNG开始 – >无论打印机需要什么使它成为’光栅模式’的工作。

该规范可在http://www.star-m.jp/eng/service/usermanual/linemode_cm_en.pdf上找到 ,如果你想提供帮助,你想要开始阅读它的页面是3-68,具体命令即使开始使用也遇到麻烦的是3-78 / 3-79。

我只能给你一个勾选标记,但我向你保证,如果你能为我提供正确方向的一点,你将会感激不尽。

编写了几个打印机驱动程序后,我可以确认,由于打印机的工作方式,文档通常会令人困惑。 你提到的文件对我来说实际上并不坏。

我认为你以光栅模式进行打印是正确的,总体来说这将是最好的结果。

从Star文档我认为你需要发送:

1. \x1b*rR Initialize raster mode 2. \x1b*rA Enter raster mode 3. \x1b*rC Clear raster data 4. \x1b*rml 4. b\x##\x##\xAA\xAA\xAA.............. 5. \x1b\x0C\x00 Raster Form feed(??) - should spit out the data. 6. \x1b*rB Clear raster data 

Obv 。 在上面的\ x1b中是ESC的C编码(即字符27 0x1b)。

从我一直在阅读的所有文档中,以下是如何在光栅模式下格式化图像。 在线模式下,垂直和水平交换完全不同。 来自热敏打印机程序设计手册(TSP552,TSP552II,TSP2000)

星光栅数据

这相当于以下字节流。

星光栅字节

在第4个命令行上,它实际上是’b’,后跟定义大小的两个字节。 此大小计算为流%256和/ 256中包含的像素数。因此,对于320×1,即0x40,0x01

因此,采用上述内容并将其插入一个简单的测试程序,您应该测试:

 char rasterImage [] = { 0x1b, '*', 'r', 'R', // Initialize raster mode 0x1b, '*', 'r', 'A', // Enter raster mode 0x1b, '*', 'r', 'C', // Clear raster data // n1 n2 d1 d2.. 0x1b, 'b', 0x2, 0, 0x00, 0x00, // data 0x1b, 'b', 0x2, 0, 0x1F, 0xF8, 0x1b, 'b', 0x2, 0, 0x3F, 0xFC, 0x1b, 'b', 0x2, 0, 0x77, 0xEE, 0x1b, 'b', 0x2, 0, 0xF8, 0x1F, 0x1b, 'b', 0x2, 0, 0xF8, 0x1F, 0x1b, 'b', 0x2, 0, 0xF8, 0x1F, 0x1b, 'b', 0x2, 0, 0x0F, 0xF0, 0x1b, 'b', 0x2, 0, 0x1F, 0xF8, 0x1b, 'b', 0x2, 0, 0x1F, 0xF8, 0x1b, 'b', 0x2, 0, 0x3E, 0x7C, 0x1b, 'b', 0x2, 0, 0x38, 0x1C, 0x1b, 'b', 0x2, 0, 0x79, 0x9E, 0x1b, 'b', 0x2, 0, 0x73, 0xCE, 0x1b, 'b', 0x2, 0, 0x73, 0xCE, 0x1b, 'b', 0x2, 0, 0xF9, 0x9F, 0x1b, 'b', 0x2, 0, 0xF8, 0x1F, 0x1b, 'b', 0x2, 0, 0xFE, 0x7F, 0x1b, 'b', 0x2, 0, 0xFF, 0xFF, 0x1b, 'b', 0x2, 0, 0xFF, 0xFF, 0x1b, 'b', 0x2, 0, 0x00, 0x00, 0x1b, 'b', 0x2, 0, 0x00, 0x00, 0x1b, 'b', 0x2, 0, 0x00, 0x00, 0x1b, 'b', 0x2, 0, 0x00, 0x00}; [self.currentDataBeingSent appendBytes:rasterImage length:sizeof(rasterImage)]; 

只需将它喷到打印机上即可获得如上所示的图片。 在这里,您可以轻松地使用确切的命令进行调整和播放,以获得有用的function。 通常这是我设法弄清楚应该做什么的唯一方法。

订正

参考。 评论。

如果每个像素有一个字节,那么你需要将它们合并为一系列位; 以下应该根据您的pastebin代码完成工作。 我还将char*更改为无符号,因为它在签名时可能会在位操作时导致问题。

 NSUInteger bitmapBytePerRow = width/8; NSUInteger bytesPerRow = 3 + bitmapBytePerRow; [self.currentDataBeingSent = [NSMutableData dataWithLength:bytesPerRow * height]; [self.currentDataBeingSent appendBytes:initializeRaster length:sizeof(initializeRaster)]; [self.currentDataBeingSent appendBytes:enterRaster length:sizeof(enterRaster)]; NSUInteger byteOffset = 0; for (NSUInteger y = 0; y < height; y++) { unsigned char *rasterCommandForRow = (unsigned char *)calloc(bytesPerRow, sizeof(char)); unsigned char *current_raster = rasterCommandForRow; *current_raster++ = '\x6B'; *current_raster++ = (width*height) % 256; *current_raster++ = (width*height) / 256; unsigned char mask = '\x80' ; unsigned char out = 0 ; for (NSUInteger x = 0; x < width; x++) { if (*(data + (byteOffset * sizeof(char)))) out |= mask ; byteOffset++; mask >>= 1 ; if( 0 == mask ) { mask = '\x80' ; *current_raster++ = out ; if( out ) lastDot = nextOut ; out = 0 ; } } // handle partially finished byte . if( ( '\x80' != mask ) && ( 0 != out ) ) *current_raster++ = out ; [self.currentDataBeingSent appendBytes:rasterCommandForRow length:bytesPerRow]; } 

rev.3a

看看Star的Mac CUPS支持 ,它有驱动程序的源代码,其中包含很多关于如何完成此操作的线索。 有时代码比文档更容易阅读。

starcupsdrv-3.1.1_mac_20100423.zip\starcupsdrv-3.1.1_mac\SourceCode\

包含starcupsdrv-src-3.1.1.tar.gz\ sub文件夹starcupsdrv\src\

查看rastertostar.c,重要的一点是计算n1 / n2值。 这些根本不是X和Y,但基于像素数,lastBlackPixel是来自源的像素数。

 putchar('b'); putchar((char) ((lastBlackPixel > 0)?(lastBlackPixel % 256):1)); putchar((char) (lastBlackPixel / 256)); 

我修改了上面的代码以包含修复程序,希望它们会更接近。 如果不扫描打印机发出的信息,那么诊断发生的情况将非常有用。

供参考jsStarUSB.cpp中 580:650之间的代码在我看来与生成缓冲区(存储在nextOut )所需的代码一致,该缓冲区包含要直接发送到打印机的格式的栅格数据。

我有预感这可能与旧的精工打印机相同,只有你的网络启用。 如果是这样,请在这里查看C代码 。 它试图输出到它认为打印机所在的串口/ dev / cua。

但是如果命令是相同的,代码应该可以帮助你。 它采用便携式位图格式作为输入,它是纯ASCII文本。

但我不知道。 微软表示 Star Micronics的工作方式与Epson LQ相同,在这种情况下,有充足的文档 。

相关链接:

  • ESC / POS PDF文档 ,数百页

  • STAR网站的命令代码


更新! ;-)尝试这个完全未经测试的代码:

 /* Call with grayscale images of height 256, width 256. */ - (void) outputraster(char* pixels, int rows) { const char initializeRaster[] = "\x1B\x2A\x72\x52"; const char enterRaster[] = "\x1B\x2A\x72\x41"; const char formFeed[] = "\x1B\x0C\x00"; const char clearRaster[] = "\x1B\x2A\x72\x43"; const char exitRaster[] = "\x1B\x2A\x72\x42"; /* The FF means 255 lines: */ char setRasterPageLength[] "\x1B\x2A\x72\x50\xFF\x0"; /* The FF FF means 256 lines and 256 rows: */ char sendRasterData[] = "\x62\xFF\xFF"; [self sendBytes:initializeRaster ofLength:sizeof(initializeRaster)]; [self sendBytes:enterRaster ofLength:sizeof(enterRaster)]; [self sendBytes:clearRaster ofLength:sizeof(clearRaster)]; [self sendBytes:setRasterPageLength ofLength:sizeof(setRasterPageLength)]; [self sendBytes:sendRasterData ofLength:sizeof(sendRasterData)]; while (rows) { for (int x = 0; x < 255; x++) { [self sendBytes:pixels[x] ofLength:256]; } rows --; } } 

更新!


我在晚上看着文档,偶然发现了如何打印出预先存储的徽标。 然后我看了如何定义该徽标,文档的那部分看起来更彻底 : 替代文字替代文字替代文字

类似打印机的位图格式说明: 替代文字

另外,请查看第34页及以上,以获取Star打印机位图格式的说明。