English 中文(简体)
使用光栅模式直接打印到以太网打印机:需要基本指导
原标题:Printing directly to Ethernet printer using raster mode : need basic guidance

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

我有一台收据打印机,需要通过iOS应用程序与之对接。打印机与设备位于同一网络上,因此我可以通过支持的“线路模式命令”对其进行寻址

我想做的是保留我已经拥有的跨平台工作的代码——即它是UIView/NSView,如果你不熟悉OS X/iOS,它只是一个标准的普通视图,我可以将其呈现为PDF/PNG格式。值得庆幸的是,打印机有一个“光栅图形”模式,这似乎正是我所需要的。

不幸的是,无论是命令规范的英语不好,还是我对基本C之外的任何东西都完全缺乏知识,或者我完全缺乏图形知识,我甚至不知道如何从现有的命令规范开始。我知道打印机和我的网络工作,因为我可以通过网络寻址并向它发送基本的馈送命令。但是,我不知道如何从巴布亚新几内亚开始->;任何打印机需要使其光栅模式工作。

该规范可在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. bx##x##xAAxAAxAA....<DATA>..........
5. x1bx0Cx00 Raster Form feed(??) - should spit out the data.
6. x1b*rB  Clear raster data

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

从我阅读的所有文档中,以下是如何在光栅模式下格式化图像。当处于行模式时,它与垂直&;水平方向被交换。来自热敏打印机程序手册(TSP552、TSP552II、TSP2000)

这相当于下面的字节流。

在第4个命令行上,它实际上是b,后面跟着两个定义大小的字节。该大小被计算为流%256和/256中包含的像素数。所以对于320x1,d 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)];

只要把它喷到打印机上,你就可以得到上面的照片。在这里,您可以轻松地调整和使用确切的命令来获得工作效果。通常,这是我唯一能弄清楚应该做什么的方法。

rev.3

参考注释。

如果每个像素有一个字节,则需要将这些字节合并为一系列位;以下内容应该根据您的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

查看mac CUPS支持来自Star,它获得了驱动程序的源代码,其中包含了许多关于如何做到这一点的线索。有时代码比文档更容易阅读。

星杯sdrv-3.3.1.1_mac_20100423.zipstarcupsdv-3.3.1.1_macSourceCode

包含starcupsdrv-src 3.1.1.tar.gz子文件夹star cupsdrvsrc

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

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

我已经修改了上面的代码以包括修复,希望能更接近。如果没有对打印机输出的内容进行扫描,诊断发生的情况将非常有用。

供参考580:650之间的代码来自jsStarUSB.cpp似乎符合生成缓冲区(存储在nextOut中)所需的内容,该缓冲区包含要直接发送到打印机的格式的光栅数据。

rev. 4 (2023)

Joshua May在评论中建议,rasterImage不需要每行都有ESC(0x1b),只需要b,只需删除0x1b就“对我有用”。

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

但是,如果命令是相同的,那么代码应该会对您有所帮助。它将可移植位图格式,它是纯ASCII文本。

但我不知道Microsoft表示Star Micronics的工作原理与Epson LQ相同,在这种情况下,充足的文档

相关链接:


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

/* Call with grayscale images of height 256, width 256. */

- (void) outputraster(char* pixels, int rows)
{
    const char initializeRaster[] =    "x1Bx2Ax72x52";
    const char enterRaster[] =         "x1Bx2Ax72x41";
    const char formFeed[] =            "x1Bx0Cx00";
    const char clearRaster[] =         "x1Bx2Ax72x43";
    const char exitRaster[] =          "x1Bx2Ax72x42";

/* The FF means 255 lines: */
    char setRasterPageLength[]         "x1Bx2Ax72x50xFFx0";


/* The FF FF means 256 lines and 256 rows: */
    char sendRasterData[] =            "x62xFFxFF";

    [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 --;
    }
}

Update!


I was looking at the docs at night, and stumbled upon how you can print out a prestored logo. Then I looked at how to define that logo, and that part of the documentation looked a lot more thorough: alt text alt text alt text

Explanations of bitmap format for a similar printer: alt text

此外,有关Star打印机位图格式的说明,请参阅第34页和页。

我希望这能帮助到一些人,但我试图使用上面Richard Harrison的代码用Python打印手机光栅。。。

我在我的系统上可以运行<code>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/





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签