Add command for printing 4 shades of grayscale image.

It works in a similar way as a monochrome print, but with few differences:
1. User needs to send 3 rows of color bitstrings for each image row.
2. Printer will stay in place while printing all 3 non-white 'colors',
it will feed the paper each third line.
3. User must multiply height by 3.
4. Command is different: cmd[0] == ASCII_GS && cmd[1] == 118 && cmd[2] == 49

E.g.
For image 200x200, user needs to send header with width 200, height 600.
Image data is arranged the following way (fourth color is blank):
25 bytes (200bits) of 1st color for first row
25 bytes (200bits) of 2nd color for first row
25 bytes (200bits) of 3rd color for first row
25 bytes (200bits) of 1st color for second row
25 bytes (200bits) of 2nd color for second row
...etc...
This commit is contained in:
Mike Sizov 2023-04-17 00:44:13 +07:00
parent 83f337fb3d
commit 6fc08fded2
4 changed files with 93 additions and 2 deletions

View File

@ -167,12 +167,13 @@
#define PRINT_STATE 0 #define PRINT_STATE 0
#define ESC_STATE 1 #define ESC_STATE 1
#define GET_IMAGE 2 #define GET_IMAGE 2
#define GET_GRAY_IMAGE 3
#define ALIGN_LEFT 0 #define ALIGN_LEFT 0
#define ALIGN_CENTER 1 #define ALIGN_CENTER 1
#define ALIGN_RIGHT 2 #define ALIGN_RIGHT 2
#define IMAGE_MAX 9224 #define IMAGE_MAX (9224*64)
#define BITS8 8 #define BITS8 8

View File

@ -683,6 +683,23 @@ void parse_cmd(CONFIG *cfg, uint8_t *cmd, uint8_t cmdidx) {
cmd_idx = 0; cmd_idx = 0;
ser_cache.idx = 0; ser_cache.idx = 0;
} }
// GS v 1 p wL wH hL hH d1…dk
if (cmd[0] == ASCII_GS && cmd[1] == 118 && cmd[2] == 49) {
uint16_t width = cmd[4] + cmd[5] * 256;
uint16_t height = cmd[6] + cmd[7] * 256;
uint16_t k;
k = width * height;
if (k <= IMAGE_MAX) {
cfg->state = GET_GRAY_IMAGE;
cfg->img->num = k;
cfg->img->idx = 0;
cfg->img->width = width;
cfg->img->need_print = 1;
}
// do not reset_cmd()
cmd_idx = 0;
ser_cache.idx = 0;
}
} }
} }
@ -700,6 +717,16 @@ void parse_serial_stream(CONFIG *cfg, uint8_t input_ch) {
reset_cmd(); reset_cmd();
cfg->state = PRINT_STATE; cfg->state = PRINT_STATE;
} }
} else if (cfg->state == GET_GRAY_IMAGE) {
cfg->img->cache[cfg->img->idx] = input_ch;
cfg->img->idx++;
if (cfg->img->idx >= cfg->img->num) { // image full
if (cfg->img->need_print == 1) {
print_gray_image8(cfg);
}
reset_cmd();
cfg->state = PRINT_STATE;
}
} else if (cfg->state == ESC_STATE) { } else if (cfg->state == ESC_STATE) {
cmd[cmd_idx] = input_ch; cmd[cmd_idx] = input_ch;
cmd_idx++; cmd_idx++;

View File

@ -340,7 +340,7 @@ void print_dots_8bit(CONFIG *cfg, uint8_t *Array, uint8_t characters,
while (y < STB_NUMBER) { while (y < STB_NUMBER) {
while (i < 10) { while (i < cfg->density) {
digitalWrite(STBx[y], HIGH); digitalWrite(STBx[y], HIGH);
delayus(HEAT_TIME + cfg->density * 46); delayus(HEAT_TIME + cfg->density * 46);
@ -837,6 +837,68 @@ uint8_t print_image8(CONFIG *cfg) {
return rv; return rv;
} }
uint8_t print_gray_image8(CONFIG *cfg) {
uint16_t height;
uint16_t x, y, addr;
uint8_t rv;
uint8_t LinePixels[MAXPIXELS];
uint8_t maxchars = PRINTER_BITS / 8;
height = cfg->img->num / cfg->img->width;
y = 0;
addr = 0;
// gray print uses 4 colors with following convention
// 3N+0th line has cfg->density/4
// 3N+1th line has cfg->density/2
// 3N+2th line has cfg->density
// white pixels should be unset in all 3 lines
uint8_t density = cfg->density;
uint8_t feed_pitch = cfg->feed_pitch;
rv = IsPaper();
ENABLE_VH;
while (y < height) {
x = 0;
while (x < cfg->img->width) {
addr = x + y * cfg->img->width;
if (cfg->img->revert_bits > 0) // LSB
LinePixels[x] = invert_bit(cfg->img->cache[addr]);
else
LinePixels[x] = cfg->img->cache[addr];
x++;
}
rv = IsPaper();
if (rv == IS_PAPER) {
if (y % 3 == 0) {
cfg->density = density / 4;
cfg->feed_pitch = 0;
}
if (y % 3 == 1) {
cfg->density = density / 2;
cfg->feed_pitch = 0;
}
if (y % 3 == 2) {
cfg->density = density;
cfg->feed_pitch = feed_pitch;
}
print_dots_8bit_split(cfg, LinePixels, x);
delayus(HEAT_TIME*2);
}
y++;
}
cfg->img->need_print = 0;
cfg->img->num = 0;
cfg->img->idx = 0;
cfg->img->width = 0;
DISABLE_VH;
return rv;
}
void print_cut_line(CONFIG *cfg) { void print_cut_line(CONFIG *cfg) {
uint8_t bs, i; uint8_t bs, i;

View File

@ -37,6 +37,7 @@ uint8_t print_lines8(CONFIG *,int,int);
uint8_t invert_bit(uint8_t a); uint8_t invert_bit(uint8_t a);
uint8_t print_image8(CONFIG *); uint8_t print_image8(CONFIG *);
uint8_t print_gray_image8(CONFIG *);
void print_cut_line(CONFIG *); void print_cut_line(CONFIG *);
void printer_set_font_mode(CONFIG *cfg, int); void printer_set_font_mode(CONFIG *cfg, int);