Algorithm to vertically flip a bitmap in a byte ar

2020-03-27 04:33发布

问题:

I am writing a class for printing bitmaps to a portable bluetooth printer in Android via Mono For Android. My class is used to obtain the pixel data from the stream so that is can be sent to the printer in the correct format. Right now the class is simple, it just reads the height, width, and bits per pixel.

Using the offset it reads and returns the pixel data to the printer. Right now I am just working with 1 bit per pixel black and white images. The bitmaps I am working with are in Windows format.

Here is the original image:

Here is the result of printing, the first image is without any transformation. And the second one is the result of modifying the BitArray with the following code:

        BitArray bits = new BitArray(returnBytes);
        BitArray flippedBits = new BitArray(bits);

        for (int i = 0, j = bits.Length - 1; i < bits.Length; i++, j--)
        {
            flippedBits[i] = bits[j];
        }

My Question is:

How do I flip the image vertically when I am working with a byte array. I am having trouble finding the algorithm for doing this, all examples seem to suggest using established graphics libraries which I cannot use.

Edit:

My Bitmap is saved in a 1 dimensional array, with the first rows bytes, then the second, third, etc.

回答1:

You need to do something like this:

BitArray bits = new BitArray(returnBytes);
BitArray flippedBits = new BitArray(bits);

for (int i = 0; i < bits.Length; i += width) {
    for (int j = 0, k = width - 1; j < width; ++j, --k) {
        flippedBits[i + j] = bits[i + k];
    }
}

If you need to mirror picture upside-down, use this code:

BitArray bits = new BitArray(returnBytes);
BitArray flippedBits = new BitArray(bits);

for (int i = 0, j = bits.Length - width; i < bits.Length; i += width, j -= width) {
    for (int k = 0; k < width; ++k) {
        flippedBits[i + k] = bits[j + k];
    }
}


回答2:

For the format with width*height bits in row order, you just need to view the bit array as a two-dimensional array.

for(int row = 0; row < height; ++row) {
    for(int column = 0; column < width; ++column) {
        flippedBits[row*width + column] = bits[row*width + (width-1 - column)];
    }
}

It would be a bit more complicated if there were more than one bit per pixel.



回答3:

You need to use two loops, the first to iterate over all the rows and the second to iterate the pixels inside each row.

for (int y = 0;  y < height;  y++)
{
    int row_start = (width/8) * y;
    int flipped_row = (width/8) * (height-1 - y);
    for (int x = 0;  x < width/8;  x++)
    {
        flippedBits[flipped_row+x] = bits[row_start+x];
    }
}