3

I'm using a zxing library in my iOS project. It's a library for reading and creating QR Codes.

From my researching and browsing around the web the process of decoding the image is made of this steps:

  • takes an image from source,
  • converts all the pixels to 255 grayscale
  • decodes the data

One thing which is not supported by this specific library is reading/decoding (and I'm pretty sure that this is missing in creating also) of inverted QRCodes.

Inverted QR Codes are basicly the same as normal codes -> but with inverted colors (white is black and black is white). But because the QRCodes standard doesn't describe the inverted QRCodes implementation and on zxing project website there is a few requests and issues, I must implement this by myself.

The method below is a good place to insert some logic to invert the pixels (unsigned char*), but because of my non-experience with C++ the result is this writing.

The grayData_ is a unsigned char* data type. And inside this variable there are grayScaled pixels from source.

What I want to do is invert these pixels.

If I'm correct this is done by unsigned char cz = (255 - val);?

unsigned char* GreyscaleLuminanceSource::getMatrix() {
    int size = width_ * height_;
    unsigned char* result = new unsigned char[size];
    if (left_ == 0 && top_ == 0 && dataWidth_ == width_ && dataHeight_ == height_) {
        memcpy(result, greyData_, size);
    } else {
        for (int row = 0; row < height_; row++) {
            memcpy(result + row * width_, greyData_ + (top_ + row) * dataWidth_ + left_, width_);
        }
    }

    //return result;
    //from this point down is my implementation

    printf(" %c", result[200]);
    printf(" %c", result[600]);
    printf(" %c", result[6000]);
    printf(" %c", result[7000]);

    for (int i = 0; i < size; i++)
    {
        int val = static_cast<int>(result[i]); 
        unsigned char cz = (255 -  val);
        result[i] = cz;
    }
    printf("******\n");
    printf(" %c", result[200]); //prints a " " char to console/terminal
    printf(" %c", result[600]); //prints a " " char to console/terminal
    printf(" %c", result[6000]); //prints a " " char to console/terminal
    printf(" %c", result[7000]); //prints a " " char to console/terminal

    return result;
}

Is this the right way to invert the pixels? And I'm not so happy with changing the data in the result variable.

Monolo
  • 18,205
  • 17
  • 69
  • 103
Francis Bagan
  • 99
  • 2
  • 8
  • how can i add/edit that C++ code in android app? – Ioan Moldovan Dec 12 '16 at 15:11
  • Francis, have you put your changes for supporting inverted barcodes with ZXing on iOS into an open source repo where others might be able to use it? We're in need of the same functionality. Thanks! – Uniphonic Feb 23 '17 at 17:18

1 Answers1

2

You don't want to print the values as characters because they aren't ASCII. Print them as unsigneds:

printf(" %u", ...);

You can simplify the loop to simply

result[i] = static_cast<unsigned char>(255 - result[i]);

The other conversions are normal integral promotion.

And you should note that ZXing uses some asymmetric heuristics when identifying codes. If you don't have a guard region surrounding the code that is, in this case, black (since the guard region is supposed to be white), it may fail to identify the code.

smparkes
  • 13,807
  • 4
  • 36
  • 61