Skip to main content
gamedev.net
🔒 Locked

flipping bitmap

Started by zorexx 3 replies 1.2k views
Original Post
zorexx
zorexx
I've made a C++ code for loading bitmap, which isnt really hard until i reached the part where i should flip the bitmap. I store the data in an array: unsigned char[width*height*3] I've tried many ways and searched through google many times but still cant get a working result :( help needed, thx in advance
cignox1
cignox1
If I understood it right, your problem is probably given by the fact that the bitmap format stores pixel in reverse order. IIRC pixels start from the lower right to the upper left, and sice unt is a byte wise inversion, channels are BGR. If what I remeber is right, you should only fill the buffer starting from the end, so that the first byte you read from the disc is the last in the destination buffer.
This, of course, onlly if what I remember is right...
darookie
darookie
I assume you want to flip the bitmap horiontally. Here's what you need to do:
Swap the lines of the upper half of the image with the lower half lines.
The index of the line to swap with on the lower half is height-i, where i is the ith line of the upper half.
Calculate the start index of a line into your array by multiplying the requested line index with the width (or pitch) of the line in bytes, which is width in pixels multiplied by pixel size in bytes.
A raw sketch of the algorithm looks like this:
void FlipImage(unsigned char * image, int width, int height, int bitsPerPixel){     // argument validation omitted for siplicity     const int pitch = width * bitsPerPixel/8;     // temporary line buffer for swapping     std::vector<unsigned char> lineBuffer(pitch);     for (int line = 0; line < height/2; ++line)     {         int lineIndex1 = GetLineIndex(line, pitch);         int lineIndex2 = GetLineIndex(height-line-1, pitch);         // store the first line into the buffer         std::copy(&image[lineIndex1], &image[lineIndex1+pitch], &lineBuffer[0]);         // copy lower line into upper half         std::copy(&image[lineIndex2], &image[lineIndex2+pitch], &image[lineIndex1]);         // copy saved upper half into lower half         std::copy(&lineBuffer[0], &lineBuffer[pitch], &image[lineIndex2]);     }}int GetLineIndex(int lineIndex, int pitch){    return lineIndex * pitch;}

Ravyne
Ravyne
Firstly, as you've figured out, cignox1 doesn't quite recall correctly: bitmaps are stored up-side down - meaning that the first color word corresponds to the lower-left corner, not the lower-right.

Second, if you intend to flip the image data for your in-memory image representation, you should simply load it in that way, rather than loading it and then flipping it. To do this, place your destination pointer at the beginning of the last row in your buffer and read in however many bytes are in the line. Next, move the destination pointer backwards to the previous line in the buffer and read in that line. Repeat until finished.

Be mindful of potential alignment constraints and the difference between the number of pixels on a line and the stride between lines. This may not be an issue for a software renderer or the like, but may be present when maintaining compatibility with an external library such as GDI, DirectX or OpenGL.

Also, I'm unsure of how compressed bitmaps are encoded: top-to-bottom or bottom-to-top, so if you support compression you should look into that further.
throw table_exception("(? ???)? ? ???");

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.