xvrh / zxing-dart

This package is a pure Dart port of the ZXing ("zebra crossing") Java library.
BSD 3-Clause "New" or "Revised" License
28 stars 8 forks source link

QR code background is transparent when it should be white #23

Open rohintoncollins opened 4 months ago

rohintoncollins commented 4 months ago

I am using your example code and was able to produce a barcode, but the background looks transparent when I think it should be white. Your example code cannot read this barcode but has no problems reading barcodes produced by other libraries.

The QR code looks alright in Finder preview on macOS, I think because the Finder preview has a white background: image

But if I open it in the Preview app, which has a grey background then it looks like this: image

This is an example of another barcode, opened by preview, which I can open with zxing2: image

My guess is that the background of the image is transparent when it should be white which is causing the decoder to fail. A shame because I really liked your library. Surely I can fix this easily enough by changing the background to white?

rohintoncollins commented 4 months ago

I was right and managed to fix this by drawing white squares. Here is the working encode function. I would suggest you update your documentation:

Uint8List encode(String mnemonic) {
  final qrcode = Encoder.encode(mnemonic, ErrorCorrectionLevel.h);
  final matrix = qrcode.matrix!;
  const scale = 4;

  var image = img.Image(
      width: matrix.width * scale,
      height: matrix.height * scale,
      numChannels: 4);

  for (var x = 0; x < matrix.width; x++) {
    for (var y = 0; y < matrix.height; y++) {
      if (matrix.get(x, y) == 1) {
        img.fillRect(image,
            x1: x * scale,
            y1: y * scale,
            x2: x * scale + scale,
            y2: y * scale + scale,
            color: img.ColorRgba8(0, 0, 0, 0xFF),
            maskChannel: img.Channel.luminance);
      } else {
        img.fillRect(image,
            x1: x * scale,
            y1: y * scale,
            x2: x * scale + scale,
            y2: y * scale + scale,
            color: img.ColorRgba8(0xFF, 0xFF, 0xFF, 0xFF),
            maskChannel: img.Channel.luminance);
      }
    }
  }

  return img.encodePng(image);
}