4

I'm writing a code to print an image using ESC * command (using an ESC POS thermal receipts printer).

Basically, I'm trying to adapt Python Algorithm for Dart/Flutter. It sounds easy : open image -> grayscale -> invert colors -> convert to b&w 1 bit:

im = Image.open(filename)
im = im.convert("L")  # Invert: Only works on 'L' images
im = ImageOps.invert(im)  # Bits are sent with 0 = white, 1 = black in ESC/POS

print(len(im.tobytes())) # len = 576 (image size: 24*24)
im = im.convert("1")  # Pure black and white
print(len(im.tobytes())) # leng = 72 (image size: 24*24)
...

I only have a problem with the last step (1 bit conversion).

As you can see, Python code (Pillow library) will decrease the number of bytes after im.convert("1") command and it's exactly what I need to correctly generate a ESC/POS command. Each value is between 0 and 255.

How to achieve it using Dart?

Here is my code:

import 'package:image/image.dart';

const String filename = './test_24x24.png';
final Image image = decodeImage(File(filename).readAsBytesSync());

grayscale(image);
invert(image);

Source image: 24px * 24px

At the end I have a grey/inverted image containing (24 * 24 * 3) bytes in RGB mode. All the r/g/b values are equal because of the greyscaling, so I can keep only one channel which gives me (24 * 24) bytes.

How can I achieve the last step im.convert("1") and keep only 24 * 3 bytes?

Jean DuPont
  • 411
  • 7
  • 22

1 Answers1

5

Iterate over the 576 grey-scale bytes, comparing each to the threshold and pack those bits into bytes (or, more conveniently, ints).

Here's an example using the helper function from package:raw, but you could just inline that as it's relatively simple.

  Uint8List img24x24 = Uint8List(24 * 24); // input 24x24 greyscale bytes [0-255]
  Uint32List img24 = Uint32List(24); // output 24 packed int with 24 b/w bits each
  final threshold = 127; // set the greyscale -> b/w threshold here
  for (var i = 0; i < 24; i++) {
    for (var j = 0; j < 24; j++) {
      img24[i] = transformUint32Bool(
        img24[i],
        24 - j,
        img24x24[i * 24 + j] > threshold, // or < threshold to do the invert in one step
      );
    }
  }
Richard Heap
  • 48,344
  • 9
  • 130
  • 112