Click here to Skip to main content
15,885,546 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
here's my code, it corrupts the photo i donno why!
** its a 24-bit bitmap **

C++
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
	fstream flower("flower.bmp", ios::in | ios::out | ios::binary);
	//declaring an array which holds data bytes belong to 800*686 pixels:
	char temp[686*800*3]; // *3 because each pixel contains 3 bytes.
	
	flower.seekg(54,ios::beg); //first 54 bytes of flower (bmp file) belong to the headers, pixels data start after that)
	flower.read(temp,686*3*800);//assigning pixel bytes to the array:
	//swapping width and height of the bitmap file:
	flower.seekg(18,ios::beg);//19,20,21,22 bytes defines the width of bmp file which is an integer and next 4 bytes belong to the height.
	char read1[4];
	char read2[4];
	flower.read(read1,4);
	flower.read(read2,4);
	flower.seekg(22,ios::beg);
	flower.write(read1,4);
	flower.seekg(18,ios::beg);
	flower.write(read2,4);
	//swapping width bytes with height bytes.
	flower.seekg(54,ios::beg);
	int k=0;
        int l=0;
	for(int i=1;i<=686;i++)
	{
		flower.seekg(54+k,ios::beg);
		for(int j=1;j<=800;j++)
		{
			flower.put(temp[l]);
			flower.seekg(1);
			flower.put(temp[++l]);
			flower.seekg(1);
			flower.put(temp[++l]);
			l++;
			flower.seekg(685*3);
		}
		k+=3;
	}
	flower.close();
}
Posted
Updated 25-Feb-15 9:44am
v8
Comments
phil.o 25-Feb-15 13:25pm    
I don't know either. Could you explain us the algorithm you used with your own words? How does it work?
Alexis i 25-Feb-15 13:46pm    
a bmf file format contains a which is 14 bytes and an image header which is 40 bytes, so from the 54th byte there is the pixels data. the 19,20,21,22 bytes defines width of image which is an int (4 bytes) and the 23,24,25,26 bytes are the height of image, so i swapped the height and width first and defined a char array and assigned the value of bmp pixels to it, and tried to exchange each pixel belonging to the width of the image with the right pixel belonging to the height.
phil.o 25-Feb-15 14:00pm    
Ok, thanks for that.
What I would do is test it toroughly againt a simple and lightweight image, so that you can more easily find where the corruption occurs.
Having a small image would be useful to validate if the header is corrupted, or the data part, or both. Dealing with a 800*600 for debugging purpose is a nightmare :)
Also, your method is not generic at all, all values (width, height, etc.) are just put in there as magic numbers. Why not using some constants and variables instead, with a meaningful naming convention?
Also, when checking Wikipedia - BMP File Format[^], it appears that it may be more complicated than you think. For example, the DIB header for Windows NT5 & 98 or later is 128 bits, not 40.
You should definitely check your assumptions about this format on a set of small test-case images gathered from various sources.
Alexis i 25-Feb-15 14:08pm    
that's a good advice ,i'd try it with a small image and try to figure out the problem.
there's something that i don't understand, isn't a 800*686 24bit image suppose to be 800*686*3+54=1646054 bytes in size? but my bmp file is 1648054 bytes! even with a 128 byte header it shouldn't be that size!
phil.o 25-Feb-15 14:26pm    
You definitely need to parse your original header, with an hex editor, and check that it is organized the way you think it is :)
From what I saw from Wikipedia's page, BMP headers are not so fixed as that, there are some optional parts that can be present. Also, Wikipedia seems to say that width and height lay respectively in offsets 18, 19, 20, 21 and 22, 23, 24, 25 (at least for a Windows BITMAPINFOHEADER).

You have to take into account that bitmaps have rows aligned on 32 bits (i.e four bytes) boundaries (they are padded). The original bitmap, having width 800 doesn't need padding (hence is size is exactly 1646454 bytes) while the rotated image needs it (686 % 4 is non-zero), that is you need to add 2 padding bytes per each row (hence the file size is 1648054, that is 800x2 longer than the original one).
The following code rotates the original image, writing the resulting one to the 'rflower.bmp' file.
C++
#include<iostream>
#include<fstream>
#include <stdint.h>
using namespace std;
int main()
{
  const int BFHS = 14; // bitmap file header size
  const int BIHS = 40; // bitmap info header size
  const int W = 800;
  const int H = 686;

  ifstream bmp("flower.bmp", ios::binary);
  ofstream rbm("rflower.bmp", ios::binary);
  char head[BFHS+BIHS];
  char rgb[3*W*H];

  // copy the header
  bmp.read(head, BFHS+BIHS);
  // swap width with height
  uint32_t temp = *(uint32_t*)&head[BFHS+4];
 *(uint32_t*)&head[BFHS+4] = *(uint32_t*)&head[BFHS+8];
 *(uint32_t*)&head[BFHS+8]= temp;
  rbm.write(head, BFHS+BIHS);
  // read pixel values
  bmp.read(rgb, 3*W*H);

  char zero[3] = {0};

  for (int y=0; y<W; ++y)
  {
    for (int x=0; x<H; ++x)
    {
      // rbm (x,y) is original bmp (y,H-1-x)
      rbm.write(&rgb[(H - x - 1) * W * 3 + y * 3], 3);
    }
    rbm.write(zero,2); // align on 32 bit boundary
  }
}
 
Share this answer
 
v2
Comments
Andreas Gieriet 25-Feb-15 18:06pm    
My 5!
Cheers
Andi
CPallini 26-Feb-15 2:28am    
Thank you.
Alexis i 25-Feb-15 18:49pm    
not working! it doesn't sort the pixels in the right place so the output is a corrupted image! the only thing it does right is swapping width and height which so does my code!
i thought the first three bytes after the header (55,56,57) belong to the upper left-hand corner of the image but now i realized they belong to the bottom left corner of the image!
CPallini 26-Feb-15 2:29am    
It works like a charm on my system. Could you please provide the original bitmap?
Rotating a matrix by 90 degree is done by the following transformation of zero-based indices:
A = N x M original matrix
B = M x N transformed matrix (i.e. rotated by +90 degree)
A[i,j] -> B[M-j-1,i]
So, you read the data into the original matrix in memory, create a transformation matrix in memory, and do transform the original cells into the transformed matrix. Finally, write the data from memory to the file (with the appropriate header and padding bytes).

Cheers
Andi

PS: Note that each row in the bit map file is padded to a multiple of 4 bytes!
 
Share this answer
 
Comments
CPallini 26-Feb-15 2:30am    
Correct, 5.
Andreas Gieriet 26-Feb-15 10:17am    
Thanks for your 5!
Cheers
Andi
If you are writing code for windows you can use .Net library to help you:
Rotate image[^] then it will work for any image.

As already mentioned it is not good to use hard-coded values, they should be parameters to your method.

Also using a Hex Editor can help you see what the file really looks like.
 
Share this answer
 
Comments
Alexis i 25-Feb-15 15:37pm    
i know i can do it using lib functions (didn't exactly know what func i should use) but i'm just trying to manipulate the file bytes to rotate it.
thanks for responding anyways.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900