Печать непосредственно на принтер Ethernet с использованием «растрового режима»: требуется базовое руководство - PullRequest
9 голосов
/ 22 октября 2010

Я наткнулся на проблему способ за пределами моей области знаний, и у меня нет наставника, чтобы обратиться за помощью в этом.

У меня есть чековый принтерМне нужно интерфейс через приложение для iOS.Принтер расположен в той же сети, что и устройства, поэтому я могу обратиться к нему через поддерживаемые «Команды линейного режима»

Что я хотел бы сделать, так это сохранить код, который у меня уже работает, который пересекается-платформа - то есть это UIView / NSView, и если вы не знакомы с OS X / iOS, это просто стандартное ванильное представление, которое я могу отобразить в форматах PDF / PNG.К счастью, принтер имеет режим «растровой графики», который, как мне кажется, мне нужен.

К сожалению, будь то плохой английский в спецификации команды, или мое полное отсутствие знаний о чем-либо, кроме базового C, илимое полное отсутствие знаний о графике, я понятия не имею, как вообще начать работать со спецификациями команд, которые у меня есть.Я знаю, что принтер и мои сети работают , потому что я могу обращаться к нему по сети и посылать ему основные команды подачи.Но я понятия не имею, как перейти от PNG -> к тому, что принтеру нужно для работы в «растровом режиме».

Спецификация доступна по адресу http://www.star -m.jp / eng./service/usermanual/linemode_cm_en.pdf, и страница, которую вы хотите начать читать, если вы хотите помочь, - 3-68, а конкретные команды, с которыми у меня возникают проблемы даже при начале работы, - на 3-78 / 3-79.

Я не могу дать вам ничего, кроме галочки, но, уверяю вас, вы будете иметь мою вечную благодарность, если вы даже сможете дать мне хоть точку в правильном направлении.

Ответы [ 2 ]

11 голосов
/ 26 октября 2010

Написав несколько драйверов принтера, я могу подтвердить, что в целом документация сбивает с толку из-за того, как работают принтеры. Документ, на который вы ссылаетесь, на самом деле не кажется мне плохим.

Я думаю, что вы правы для печати в растровом режиме, и в целом это даст наилучшие результаты.

Из документации 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

Аверс . в вышеприведенном \ x1b - кодировка E ESC (то есть символ 27 0x1b).

Из всей документации, которую я читал, ниже показано, как изображения должны быть отформатированы в растровом режиме. Когда в линейном режиме это полностью отличается, поскольку вертикальные и горизонтальные меняются местами. С РУКОВОДСТВО ПО ПРОГРАММИРОВАНИЮ ТЕПЛОВОГО ПРИНТЕРА (TSP552, TSP552II, TSP2000)

Star Raster Data

Это соответствует следующему потоку байтов.

Star Raster bytes

В 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)];

Просто впрысните это в принтер, и вы получите изображение, как указано выше. Здесь вы можете легко настроить и поиграть с точными командами, чтобы получить что-то, что работает. Зачастую это единственный способ, который мне когда-либо удавалось выяснить, что должно быть сделано.

rev.3

Ref. комментарии.

Если у вас есть байт на пиксель, вам нужно объединить их в последовательность битов; следующее должно делать работу, основываясь на вашем коде вставки. Я также изменил 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, он получил исходный код для драйвера, который содержит множество подсказок о том, как это сделать. Иногда код намного легче читать, чем документацию.

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 & Y, но на основе количества пикселей lastBlackPixel - это количество пикселей от источника.

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

Я изменил код выше, чтобы включить исправления, надеюсь, это будет ближе. Если не опубликовать сканирование того, что выходит из принтера, будет полезно диагностировать, что происходит.

Для справки. Код между 580: 650 из jsStarUSB.cpp , мне кажется, соответствует тому, что вам нужно для создания буфера (хранящегося в nextOut), который содержит растровые данные формат для отправки непосредственно на принтер.

4 голосов
/ 22 октября 2010

У меня есть догадка, это может быть то же самое, что и старые принтеры Seiko, только у вас включена сеть.Если это так, взгляните на код C здесь .Он пытается вывести на последовательный порт / dev / cua, где он считает, что принтер.

Но если команды совпадают, код должен помочь вам.В качестве входных данных он принимает Portable Bitmap Format , который представляет собой простой текст ASCII.

Но я не знаю. Microsoft указывает Star Micronics работает так же, как Epson LQ, в этом случае имеется полная документация .

Ссылки по теме:


Обновление!;-) Попробуйте это, полностью непроверенный код:

/* 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 --;
    }
}

Обновление! Я смотрел на документы по ночам и наткнулся на то, как можно распечатать заранее сохраненный логотип.Затем я посмотрел, как определить этот логотип, и эта часть документации выглядела намного более тщательной : alt text alt text alt text

Пояснениярастрового формата для аналогичного принтера : alt text

Кроме того, см. на страницах 34 и объяснение формата растрового изображениязвездного принтера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...