我偶然发现了方式超出我的专业领域的问题,而且我没有导师可以求助于此。
我有一个收据打印机,我需要通过iOS应用程序进行交互。打印机与设备位于同一网络上,因此我可以通过支持的“线路模式命令”来解决它
我想做的是保持我已经跨平台工作的代码 - 即它是一个UIView / NSView,如果你不熟悉OS X / iOS,它只是一个标准的香草视图,我可以渲染成PDF / PNG格式。值得庆幸的是,打印机具有“光栅图形”模式,似乎是我所需要的。
不幸的是,无论是命令规范的破坏英语,还是我对基本C以外的任何东西的完全缺乏了解,或者我完全缺乏关于图形的知识,我都不知道如何从命令规范开始有。我知道打印机和我的网络工作因为我可以通过网络解决它并发送基本的feed命令。但是,我不知道如何从PNG出发 - >无论打印机需要使其成为“光栅模式”。
该规范在http://www.star-m.jp/eng/service/usermanual/linemode_cm_en.pdf提供,如果您想提供帮助,您想要开始阅读的页面是3-68,并且我甚至开始使用的特定命令都已开启3-78 / 3-79。
我只能给你一个复选标记,但我向你保证,如果你能为我提供正确方向的一点,你将会感激不尽。
答案 0 :(得分:11)
编写了一些打印机驱动程序后,我可以确认,由于打印机的工作方式,文档通常会令人困惑。你提到的文件对我来说实际上并不坏。
我认为你以光栅模式进行打印是正确的,总体来说这会带来最好的结果。
从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....<DATA>..........
5. \x1b\x0C\x00 Raster Form feed(??) - should spit out the data.
6. \x1b*rB Clear raster data
OBV 。在上面的\ x1b中是ESC的C编码(即字符27 0x1b)。
在我阅读的所有文档中,以下是如何在光栅模式下格式化图像。当在线模式时,它与垂直和放大完全不同。水平交换。来自THERMAL PRINTER PROGRAMMER'S MANUAL (TSP552,TSP552II,TSP2000)
这相当于以下字节流。
在第4个命令行上,它实际上是'b',后跟两个字节来定义大小。此大小计算为流%256和/ 256中包含的像素数。因此,对于320x1,'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)];
只需将它喷到打印机上即可获得如上所示的照片。在这里,您可以轻松调整和播放确切的命令,以获得有用的功能。通常这是我设法弄清楚应该做什么的唯一方法。
参考。评价。
如果每个像素有一个字节,那么你需要将它们合并为一系列位;以下应该根据您的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];
}
查看Star的Mac CUPS support,它有驱动程序的源代码,其中包含很多关于如何完成此操作的线索。有时代码比文档更容易阅读。
starcupsdrv-3.1.1_mac_20100423.zip\starcupsdrv-3.1.1_mac\SourceCode\
包含starcupsdrv-src-3.1.1.tar.gz\
子文件夹starcupsdrv\src\
查看rastertostar.c,重要的一点是计算n1 / n2值。这些根本不是X&amp; Y但是基于像素数,lastBlackPixel是来自像素的像素数。
putchar('b');
putchar((char) ((lastBlackPixel > 0)?(lastBlackPixel % 256):1));
putchar((char) (lastBlackPixel / 256));
我修改了上面的代码以包含修复程序,希望它们会更接近。如果不对扫描仪发出的信息进行扫描,那么诊断发生的情况将非常有用。
供参考在jsStarUSB.cpp中,580:650之间的代码似乎与生成缓冲区(存储在nextOut
中)所需的内容一致,该缓冲区包含格式中的栅格数据直接发送到打印机。
答案 1 :(得分:4)
我有预感,这可能与旧的Seiko打印机相同,只有你的网络启用了。如果是这样,请查看C code here。它试图输出到它认为打印机所在的串口/ dev / cua。
但是如果命令相同,代码应该可以帮到你。它将Portable Bitmap Format作为输入,这是纯ASCII文本。
但我不知道。 Microsoft indicates Star Micronics与Epson LQ的工作方式相同,在这种情况下有ample documentation。
相关链接:
更新! ;-)尝试这个完全未经测试的代码:
/* 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 --;
}
}
更新!
<小时/> 我在晚上看着文档,偶然发现了如何打印出预先存储的徽标。然后我看了如何定义该徽标,文档的那部分看起来是lot more thorough:
位图格式for a similar printer的解释:
另外,look at pages 34 and on用于解释Star打印机的位图格式。
答案 2 :(得分:0)
我希望这对某人有所帮助,但我试图使用上面 Richard Harrison 的代码在 Python 中打印电话光栅...
我可以在我的系统上运行 python3 raster.py > /dev/usb/lp0
并得到预期的输出!!希望它显示了你需要的东西。我交叉引用了要打印的文件的字节数,以及图形模式手册。
import sys
buf = [
0x1b, ord('*'), ord('r'), ord('A'), # enter raster mode
0x1b, ord('*'), ord('r'), ord('P'), ord('0'), 0x00, # continuous mode
ord('b'), 0x2, 0, 0x00, 0x00,
ord('b'), 0x2, 0, 0x1F, 0xF8,
ord('b'), 0x2, 0, 0x3F, 0xFC,
ord('b'), 0x2, 0, 0x77, 0xEE,
ord('b'), 0x2, 0, 0xF8, 0x1F,
ord('b'), 0x2, 0, 0xF8, 0x1F,
ord('b'), 0x2, 0, 0xF8, 0x1F,
ord('b'), 0x2, 0, 0x0F, 0xF0,
ord('b'), 0x2, 0, 0x1F, 0xF8,
ord('b'), 0x2, 0, 0x1F, 0xF8,
ord('b'), 0x2, 0, 0x3E, 0x7C,
ord('b'), 0x2, 0, 0x38, 0x1C,
ord('b'), 0x2, 0, 0x79, 0x9E,
ord('b'), 0x2, 0, 0x73, 0xCE,
ord('b'), 0x2, 0, 0x73, 0xCE,
ord('b'), 0x2, 0, 0xF9, 0x9F,
ord('b'), 0x2, 0, 0xF8, 0x1F,
ord('b'), 0x2, 0, 0xFE, 0x7F,
ord('b'), 0x2, 0, 0xFF, 0xFF,
ord('b'), 0x2, 0, 0xFF, 0xFF,
ord('b'), 0x2, 0, 0x00, 0x00,
ord('b'), 0x2, 0, 0x00, 0x00,
ord('b'), 0x2, 0, 0x00, 0x00,
ord('b'), 0x2, 0, 0x00, 0x00,
0x1b, ord('*'), ord('r'), ord('b') # end raster mode
]
blob = bytearray(buf)
sys.stdout.buffer.write(blob)
编辑:在此基础上,我创建了一个 Python 库,该库将获取图像并将其转换为所需的光栅命令...https://pypi.org/project/StarTSPImage/