CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 5 of 5
  1. #1
    Join Date
    Mar 2005
    Posts
    23

    Colors Shifting In 24 bit Bitmap.

    Hello,

    I am experiencing some difficulty changing the colors of a bitmap. For each pixel of a bitmap I am assigning it a shade of blue based on its horizontal placement. The function is similar to

    pixel.blue = ((x*v)%n)%256,
    pixel.green = 0,
    pixel.red = 0.

    x: Position from 0 to bitmap.width - 1.
    v: Variation in color [0 to 255].
    n: Maximum number of colors [0 to 255].

    The expected bitmap begins with columns of low intensity blue that progress to high intensity blue and then repeat. However, sometimes there are diagonal columns or no columns, and there are also pixels with shades of just red or just green. From what i have seen it appears that the first part of each row is being misplaced somehow and that the cutoff is not happening at a pixel boundry, resulting in other colors. To further complicate matters, the behavior does not appear if I use pixel.blue = 200 (or any other constant) and is also dependant on the values of v, n, and bitmap.width.

    I have included the mini project that I am using to try to understand the problem. Thank you for your help.

    dremmuel
    Attached Files Attached Files

  2. #2
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Colors Shifting In 24 bit Bitmap.

    The memory used by each row of a bitmap must begin on a DWORD-aligned boundary. If a row has a non-DWORD number of bytes, then the end of the row is padded out to the next DWORD boundary, so that the subsequent row begins correctly. See http://msdn2.microsoft.com/en-us/lib...37(VS.85).aspx

    By default, bitmap data is bottom-up in its format. ... The scan lines are DWORD aligned, except for RLE-compressed bitmaps. They must be padded for scan line widths, in bytes, that are not evenly divisible by four, except for RLE compressed bitmaps. For example, a 10- by 10-pixel 24-bpp bitmap will have two padding bytes at the end of each scan line.
    Your problem, which manifests itaself in dependence on bitmap width (among other things) might be due to incorrect alignment for each row, and failure to provide needed padding at the end of a row.

    Mike

  3. #3
    Join Date
    Mar 2005
    Posts
    23

    Re: Colors Shifting In 24 bit Bitmap.

    Mike,

    Thank you for your reply. The padding formula I am using is

    int n = sizeof(DWORD)
    padding = (n - ((width*3) % n)) % n

    For the number of bytes in the image I am using

    nImageBytes = height(width*3 + padding)

    I am indexing a pixel by

    BYTE *bytes = new BYTE[nImageBytes];
    ...
    y in [0, height-1]
    x in [0, width-1]
    bytes[y*(width*3 + padding) + x*3 + 0] //blue
    bytes[y*(width*3 + padding) + x*3 + 1] //green
    bytes[y*(width*3 + padding) + x*3 + 2] //red

    I do not think there is a padding problem since some good data sets are produced for widths of w, w+1, w+2, and w+3. Please let me know if I am off on something. Thanks.
    Last edited by dremmuel; February 14th, 2008 at 03:17 PM.

  4. #4
    Join Date
    Mar 2005
    Posts
    23

    Re: Colors Shifting In 24 bit Bitmap.

    I solved the problem. I was using standard IO functions to read and write the bitmap information. For some reason ofstream.write was adding bytes to each row. The bitmaps are being written correctly using file handles. Thank you for looking at the problem. Thanks Mike for the post.

    dremmuel

  5. #5
    Join Date
    Nov 2002
    Location
    California
    Posts
    4,556

    Re: Colors Shifting In 24 bit Bitmap.

    Now that you have done the hard work to find the answer, the reason is now evident:
    Code:
    void CreateNewBM(int Width, int Height, char *DestBMName)
    {
    	// ... << snip  >>
    
    	//Write bitmap to DestBMNAME
    	//--------------------------
    	ofstream outI(DestBMName);
    	outI.write((char*)&bmFH, sizeof(BITMAPFILEHEADER));
    	outI.write((char*)&bmIH,  sizeof(BITMAPINFOHEADER));
    	outI.write((char*)bytes, bmIH.biSizeImage);
    	outI.close();
    
    	// ... etc
    }
    ofstream outI(DestBMName) opens the file in text mode. Try opening it in binary mode using ios::binary:
    Code:
    ofstream outI(DestBMName, ios::binary);
    The same is probably true of your input streams too.

    Mike

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured