도움받은 사이트 : https://developer.zebra.com/thread/34694

 

ZPL 의 ^GF 명령어를 통해 Bitmap 데이터를 조합해 Zebra 프린터로 출력할 수 있습니다.

아래는 Bitmap 파일을 읽어 Zebra 프린터로 출력하기 위한 ZPL 코드를 생성하는 방법을 정리합니다.

 

테스트는 Visual Sutdio 2015 Express 에서 진행했으며

아래 test() 함수는 BMP 헤더 구조체만 정의하면 리눅스에서도 사용할 수 있을겁니다.

 

 

♣ Bitmap 이미지 생성

Zebra 프린터는 흑백으로 출력합니다.

이에 출력하려는 bmp 이미지를 단색만 사용하도록 설정합니다.

저는 윈도우 그림판에서

  1. 메뉴
  2. 다른이름으로 저장
  3. BMP 그림 선택
  4. 아래 파일형식 : 단색 비트맵 (~~) 선택

으로 저장합니다.

 

 

첨부파일 hosang.bmp 는 위 이미지를 단색으로 저장하였고 크기는 67x32 입니다.

(※ hosang.bmp 파일은 아래 이미지를 우클릭해서 다른이름으로 저장하여 사용하시기 바랍니다.)

 

  -> 이거 우클릭 후, 저장~

 

 

 

♣ Bitmap Padding

단색 Bitmap 의 경우, 한 pixel 을 저장하는데 한 bit 를 소모합니다.

한 Byte는 8bits 이니 위 이미지의 한줄인 67 픽셀을 저장하는데 72 Bits ( 9 Bytes) 가 소모될 겁니다.

 

하지만 실제 파일을 열어보면 80 Bits (10 Bytes) 가 사용됩니다.

즉 단색 bitmap 은 16 bits ( 2 Bytes) 단위로 끊어 처리합니다.

 

 

실제 이미지 크기는 67 x 32 이지만,

bmp 파일에 저장된 이미지 영역은 80 x 32 입니다.

이 때 80 은 16 의 배수입니다.

 

즉 파일의 이미지 데이터 영역은 80x32 / 8 = 320 Bytes 가 됩니다

 

이에 bmp Info 에서 실제 width (67px) 를 얻어 68~80 번째 데이터는 무시하는 작업이 필요합니다.

 

그리고 상하로 뒤집어 저장하는 bmp 의 이미지 데이터를 다시 원래대로 돌려 놓습니다.

 

♣ ZPL Code

ZPL 코드로 Bitmap 처리를 하기 위해선 ^GF 명령어를 이용합니다.

( ^GF 관련 설명은 Zebra 사의 ZPL 설명서 참조)

본 글은 ^GF 의 마지막 항목인 데이터 영역을 만들기 위함입니다.

 

아래 test() 함수는 단색 타입의 bmp 파일을 읽어 ZPL 의 Data 영역을 만드는 함수입니다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
int test()
{
    string strZpl ;
    char szText[128] ;
    char szBmp[32] ;
 
    BITMAPFILEHEADER bmFile ;
    BITMAPINFOHEADER bmInfo ;
 
    int px = 100 ;
    int py = 100 ;
 
    FILE* fpBmp = fopen("./hosang.bmp""rb") ;
 
    if(!fpBmp)
    {
//        MyLog("genBitmap fopen Error\r\n") ;
        return -1 ;
    }
 
    // read BMP Header and Infomation.
    fread(&bmFile, sizeof(BITMAPFILEHEADER), 1, fpBmp) ;
    fread(&bmInfo, sizeof(BITMAPINFOHEADER), 1, fpBmp) ;
 
    // Move Image Data offset.
    fseek(fpBmp, bmFile.bfOffBits, SEEK_SET) ;
 
    strZpl.clear() ;
    strZpl += "^XA" ;
 
    sprintf(szText, "^FO%d,%d", px, py) ;
    strZpl += szText ;
 
    int width = ((bmInfo.biWidth / 32) + 1) * 4 ;
    int mod = (bmInfo.biWidth) % 32 ;
    int realWidth = (bmInfo.biWidth + 7) / 8 ;
 
    int imageSize = realWidth * bmInfo.biHeight ;
    int shiftCount = 0 ;
 
    sprintf(szText, "^GFA,%d,%d,%d,", imageSize, imageSize, realWidth) ;
    strZpl += szText ;
 
    list<string>         listRow ;
    list<string>::iterator     listRowIter ;
 
    string strRow ;
 
    for(int ii = 0; ii < bmInfo.biHeight; ii++)
    {
        strRow.clear() ;
        for(int jj = 1; jj <= width; jj++)
        {
            fread(szBmp, 1, 1, fpBmp) ;
 
            if(jj > realWidth)
                continue ;
 
            if(jj == realWidth)
            {
                shiftCount = 8 - ((bmInfo.biWidth + 8) % 8) ;
                for(int kk = 0; kk < shiftCount; kk++)
                {
                    szBmp[0] |= ((szBmp[0] >> kk) | 0x01) ;
                }
            }
 
            szBmp[0] ^= 0xff ;
            szBmp[1] = '\0' ;
            sprintf(szText, "%02X", szBmp[0] & 0xff) ;
            strRow += szText ;
        }
 
        listRow.push_front(strRow) ;
    }
 
    listRowIter = listRow.begin() ;
    for(; listRowIter != listRow.end(); listRowIter++)
    {
        strZpl += *listRowIter ;
    }
    fclose(fpBmp) ;
 
    strZpl += "^FS";
    strZpl += "^XZ" ;
    
    FILE* fpZpl = fopen("./myZpl.txt""wt") ;
    fprintf(fpZpl, "%s", strZpl.c_str()) ;
    fclose(fpZpl) ;
 
    return 1 ;
}

 

위 함수가 실행되면 myZpl.txt 파일에 ZPL 코드가 아래와 같이 저장됩니다.

보기 편하게 줄로 나누어 봤습니다.

유효한 값에 형광펜을 칠해보면 이미지의 모양이 보입니다.

 

myZpl.txt

------------------------------------------

^XA^FO100,100^GFA,288,288,9,

0007C0000000003C00
0007C000001E003C00
0007C000001E003C00
0007C000001E003C00
1FFFFFF0001E003C00
1FFFFFF0001E003C00
1FFFFFF0001E003C00
1FFFFFF0001F003C00
00000000003F003FFE
001FF000007F803FFE
00FFFE00007FC03FFE
01FFFF0000F3E03FFE
03FFFF8001F1F83C00
07E00FC007E0FE3C00
078003C00FC07C3C00
078003C01F803C3C00
078003C00F00083C00
078007C00400003C00
07E00FC00000000000
03FFFF800001FF0000
01FFFF00000FFFE000
003FF800003FFFF000
0007C000007FFFF800
0007C000007E00FC00
0007C00000F8003C00
FFFFFFFE00F8003C00
FFFFFFFE00F8003C00
FFFFFFFE007E00FC00
FFFFFFFE007FFFF800
00000000003FFFF000
00000000000FFFE000
000000000001FF0000

^FS^XZ

 

위 ZPL 코드를 Zebra 프린터 (필자의 경우, ZM400 300dpi) 로 전송하면 아래와 같이 이미지가 출력됩니다.

 

 

 

 

 

 

 

 

 

 

+ Recent posts