Invert pixels

Feb 12, 2012 at 1:50pm
First of all - great site with a lot of infos. I'm sure I'll be visiting this site a "few" times more :)

Now my question/problem:
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 preety 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 no expirience 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 wana do is invert this pixels.

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


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
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 result variable.


Sory for my bad english language.

By,
Francis
Feb 12, 2012 at 3:23pm
Yes, 255-val is the correct way to invert the pixels

You don't need to cast to int, just do the arithmetic on the unsigned chars

Personally, I would have a seperate member function to invert the pixels from the one that gets the data
Feb 13, 2012 at 5:51pm
@mik2718 Thank you

Here is the complete method after correcting a few things and implementing that scanning works for normal and inverted codes.


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
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_);
        }
    }

    struct timeval start;
    gettimeofday(&start,NULL);

    float ss = start.tv_usec / 1000.0;
    ss = ss - (int)ss; 
    ss = ss / 20.0 * 100; 
    int tmp = ss - (ss - (int)ss); 
    if((tmp % 2 == 0)) {
        for (int i = 0; i < size; i++)
        {
            result[i] = static_cast<unsigned char>(255 - result[i]);
        }
    }
    return result;
}
Topic archived. No new replies allowed.