C + + BMP (24-bit true color) image processing (4)------Image rotation

Source: Internet
Author: User
Tags bmp image cos fread sin truncated

After one months, Csdn seems to finally seem to be the article List of reading information to zero bug fixed, and then put the article to do the final work when writing to test the results, but do not like the same as the last article on the Pit dad Ah!

This article is about the rotation of the image, not a new topic. But now because a lot of tools such as MATLAB, OpenCV and so on to write the algorithm to the user call, resulting in most users only know it is not known why, so review is also good.

The rotation of an image is at the bottom of the point where each pixel rotates at a certain angle around a certain center. If you are writing code, the angle of rotation and the center of the circle should be the known condition, our first idea is to extract the coordinates of the new pixel after the image has been rotated according to the known conditions. This idea is clearly not wrong, but one problem is that after the rotation of the image some pixels have been transferred out to the size of the image, and some other pixels can not correspond to the original image. This makes programming complicated with such a mindset. Therefore, we think in turn, we should first plan the rotated image, and then a method to calculate the new image each pixel point corresponds to the original image of the pixel point, if the corresponding pixel is in the original image where, if not the pixel should be the value of how much. In this way we can iterate through all the pixels of the new image to get the rotated image.

OK, we've got the idea of rotating the image clear. What we don't know now is the pixel-point correspondence before and after the image is rotated. This relationship is slightly more complicated, I refer to the calculation method of this blog, the following to deduce or reproduce.


See, after the derivation above, we are going to get X, Y, from X. This means that the final form we're going to get is:

X=f (x ', y ');

Y=g (x ', y ')

It's like this. OK, the calculation formula is deduced as follows (written in Word, the style is slightly different ...). ):


OK, the theoretical work done, the next is the programming, it is important to note that the point of rotation after the image points to the position of the image before rotation is basically not likely to be positive, so it is necessary to use bilinear interpolation (the theory of the specific analysis in the previous article in detail mentioned).

The main code is as follows:

/******************* image rotation ******************/int centerofrotation_x = mydraw_width/2;//Rotation Center x coordinate int centerofrotation_y = mydraw_height/2;//Rotation Center y-coordinate double degree = 60;//counterclockwise rotation angle Double radian = degree/180 * pi;//angle to radians for (int hnum = 0; hnum < Mydraw_height; hnum++) for (int wnum = 0; wnum < mydraw_width; wnum++) {int pixel_point = hnum*write_width + wnum * 3;//Map scale transform image array position offset D Ouble d_original_img_wnum = (wnum-centerofrotation_x) *cos (radian)-(hnum-centerofrotation_y) *sin (radian) + CENTEROFR Otation_x;double d_original_img_hnum = (wnum-centerofrotation_x) *sin (radian) + (hnum-centerofrotation_y) *cos (radian ) + centerofrotation_y;if (d_original_img_wnum<0 | | d_original_img_wnum>width | | d_original_img_hnum<0 | | d_ Original_img_hnum>height)//Cannot find the relationship with the original image {Pcolordatamid[pixel_point] = pcolordatamid[pixel_point + 1] = Pcolordatamid[pixel_point + 2] = 0;continue;} int i_original_img_hnum = D_original_img_hnum;int I_original_img_wnum = d_original_img_wnum;double distance_to_a_x = d_original_img_wnum-i_original_img_wnum;//horizontal distance to point A in the original image double distance_to_a_y = d_original_img_hnum-i_original _img_hnum;//the vertical distance from point A in the original image int original_point_a = i_original_img_hnum*l_width + i_original_img_wnum * 3;//array position offset, Corresponds to the starting point of each pixel point RGB of the image, equivalent to point a int original_point_b = I_original_img_hnum*l_width + (i_original_img_wnum + 1) * 3;//array position offset, corresponding to the graph Pixels like the starting point of RGB, equivalent to point bint Original_point_c = (i_original_img_hnum + 1) *l_width + i_original_img_wnum * 3;//array position offset, Corresponds to the starting point of each pixel point RGB of the image, equivalent to point c int original_point_d = (i_original_img_hnum + 1) *l_width + (I_original_img_wnum + 1) * 3;//array position offset, Corresponds to the starting point of each pixel point RGB of the image, equivalent to point D if (i_original_img_hnum = = mydraw_height-1) {Original_point_c = Original_point_a;original_ Point_d = Original_point_b;} if (I_original_img_wnum = = mydraw_width-1) {original_point_a = Original_point_b;original_point_c = Original_point_d;} Pcolordatamid[pixel_point] =pcolordata[original_point_a] * (1-distance_to_a_x) * (1-distance_to_a_y) +pColorData[ Original_point_b] * distance_to_a_x* (1- distance_to_a_y) +pcolordata[original_point_c] * distance_to_a_y* (1-distance_to_a_x) +pColorData[original_point_c] * distance_to_a_y*distance_to_a_x;pcolordatamid[pixel_point + 1] =pcolordata[original_point_a + 1] * (1-distance_to_a_ X) * (1-distance_to_a_y) +pcolordata[original_point_b + 1] * distance_to_a_x* (1-distance_to_a_y) +pColorData[original_ Point_c + 1] * distance_to_a_y* (1-distance_to_a_x) +pcolordata[original_point_c + 1] * distance_to_a_y*distance_to_a_x; Pcolordatamid[pixel_point + 2] =pcolordata[original_point_a + 2] * (1-distance_to_a_x) * (1-distance_to_a_y) +pColorData [Original_point_b + 2] * distance_to_a_x* (1-distance_to_a_y) +pcolordata[original_point_c + 2] * distance_to_a_y* (1-di stance_to_a_x) +pcolordata[original_point_c + 2] * distance_to_a_y*distance_to_a_x;} /******************* Image Rotation ******************/

the entire project code is as follows:

#include <string.h> #include <math.h> #include <stdio.h> #include <stdlib.h> #include <ma Lloc.h> #include <time.h>//time-related header files, where functions can be used to calculate image processing speed, # widthbytes (bits) ((bits) +31)/32*4)// Multiples of 4byte for image width # # define Mydraw_height 1054//target Image Height # define Mydraw_width 1500//target image width # define Pi 3.1415926535typedef unsigned char byte;typedef unsigned short word;typedef unsigned long dword;typedef long long;//bitmap file header          The information structure definition//which does not contain the file type information (due to the structure of the memory structure of the decision, if added will not be able to read the file information correctly) typedef struct TAGBITMAPFILEHEADER {DWORD bfsize; File size word bfReserved1; Reserved words, regardless of word bfReserved2;       Reserved word, ibid. DWORD bfoffbits; The number of offset bytes of the actual bitmap data, that is, the sum of the first three part lengths and the bitmapfileheader;//information header Bitmapinfoheader, is also a structure defined as follows: typedef struct TAGBITMAPINFOHEADER         {//public:dword bisize;       Specifies the length of this structure as 40LONG biwidth;       Bitmap wide long biheight;       Bitmap high word biplanes;     The number of planes is 1WORD biBitCount;  Using the color number, can be 1,2,4,8,16,24, the new can be 32DWORD bicompression; Compression mode, which can be 0,1,2, where 0 means noCompression DWORD biSizeImage;      The actual bitmap data occupies a number of bytes long bixpelspermeter;//x direction resolution long biypelspermeter;//y direction resolution DWORD biclrused; The number of colors used, and if 0, indicates the default value (2^ color digits) of the DWORD biclrimportant; The number of important colors, if 0, indicates that all colors are important} bitmapinfoheader;void main () {Long now = 0;now = Clock ();//Store image processing start time Bitmapfileheader Bithead, Writebithead; Bitmapinfoheader Bitinfohead, Writebitinfohead; file* pfile;//input file file* wfile;//output file char strfile[50] = "15.bmp";//Open Image path, BMP image must be 24-bit true Color format char strfilesave[50] = "16. BMP ";//image storage path after processing fopen_s (&pfile, strfile," RB ");//File Open image fopen_s (&wfile, Strfilesave," WB ");// Open file for storing modified image to prepare//read bitmap header information for WORD filetype;fread (&filetype, 1, sizeof (WORD), pfile); Fwrite (&filetype, 1, sizeof (WORD), wfile), if (fileType! = 0x4d42) {printf ("file is not. bmp file!"); return;} Read the bitmap header information Fread (&bithead, 1, sizeof (Tagbitmapfileheader), pfile), Writebithead = bithead;//because the Intercept image header and the source file header are similar, So first, the source file header data is given to the truncated file header//Read the bitmap information header information Fread (&bitinfohead, 1, sizeof (Bitmapinfoheader), pfile); writebitinfohead = Bitinfohead;//similar to bitmap file header writebitinfohead.biheight = mydraw_height;//rewrite bitmap height for intercept file Writebitinfohead.biwidth = mydraw_width;// Rewrite bitmap width for intercept file int mywritewidth = widthbytes (Writebitinfohead.biwidth*writebitinfohead.bibitcount);// BMP image The actual bitmap data area width is a multiple of 4byte, in this calculation of the actual data area width Writebitinfohead.bisizeimage = mywritewidth*writebitinfohead.biheight;// Calculate bitmap actual data area size Writebithead.bfsize = writebitinfohead.bisizeimage;//Bitmap file header size to bitmap data area size plus 54bytefwrite (& Writebithead, 1, sizeof (Tagbitmapfileheader), wfile);//write back the bitmap file header information to the output file Fwrite (&writebitinfohead, 1, sizeof ( Bitmapinfoheader), wfile);//write back the bitmap information header information to the output file int width = bitinfohead.biwidth;int height = bitinfohead.biheight;// Allocate memory space to store the source graph in memory int l_width = Widthbytes (Width*bitinfohead.bibitcount);//Calculate the actual width of the bitmap and make sure it is a multiple of 4byte int write_width = Widthbytes (Writebitinfohead.biwidth*writebitinfohead.bibitcount);//Calculate the actual width of the bitmap and make sure it is a multiple of 4byte byte *pcolordata = ( BYTE *) malloc (height*l_width);//Open memory space to store image data memset (pcolordata, 0, height*l_width); byte *pcolordatamid = (BYTE *) malloc (mywritewidth*myDraw_height);//Open memory space to store image processing after data memset (pcolordatamid, 0, mywritewidth*mydraw_height); long ndata = Height*l_width; Long write_ndata = mywritewidth*mydraw_height;//truncated bitmap data area length definition//Read the bitmap data information into the array fread (Pcolordata, 1, Ndata, pfile);// Image processing can be achieved by manipulating this part of the data/******************* image processing part ******************//******************* image rotation ******************/int centerofrotation_x = mydraw_width/2;//Rotation Center x coordinate int centerofrotation_y = mydraw_height/2;//Rotation Center y-coordinate double degree = 60;//inverse Needle rotation angle Double radian = degree/180 * pi;//angle to radians for (int hnum = 0, hnum < mydraw_height; hnum++) for (int wnum = 0; Wnum & Lt Mydraw_width; wnum++) {int pixel_point = hnum*write_width + wnum * 3;//Map scale transform image array position offset double d_original_img_wnum = (Wnum-centerofrotati on_x) *cos (radian)-(hnum-centerofrotation_y) *sin (radian) + centerofrotation_x;double D_original_img_hnum = (wnum-cen terofrotation_x) *sin (radian) + (hnum-centerofrotation_y) *cos (radian) + centerofrotation_y;if (d_original_img_wnum <0 | | D_original_img_wnum>width | | D_original_img_hnum<0 | | D_original_img_hnum>height)//Cannot find the relationship with the original image {Pcolordatamid[pixel_point] = pcolordatamid[pixel_point + 1] = Pcolordatamid[pixel_point + 2] = 0;continue;} int i_original_img_hnum = D_original_img_hnum;int I_original_img_wnum = d_original_img_wnum;double distance_to_a_x = D_ original_img_wnum-i_original_img_wnum;//horizontal distance to point A in the original image double distance_to_a_y = D_original_img_hnum-i_original_img_ hnum;//the vertical distance from point A in the original image int original_point_a = i_original_img_hnum*l_width + i_original_img_wnum * 3;//array position offset, Corresponds to the starting point of each pixel point RGB of the image, equivalent to point a int original_point_b = I_original_img_hnum*l_width + (i_original_img_wnum + 1) * 3;//array position offset, corresponding to the graph Pixels like the starting point of RGB, equivalent to point bint Original_point_c = (i_original_img_hnum + 1) *l_width + i_original_img_wnum * 3;//array position offset, Corresponds to the starting point of each pixel point RGB of the image, equivalent to point c int original_point_d = (i_original_img_hnum + 1) *l_width + (I_original_img_wnum + 1) * 3;//array position offset, Corresponds to the starting point of each pixel point RGB of the image, equivalent to point D if (i_original_img_hnum = = mydraw_height-1) {Original_point_c = Original_point_a;original_ Point_d = orIginal_point_b;} if (I_original_img_wnum = = mydraw_width-1) {original_point_a = Original_point_b;original_point_c = Original_point_d;} Pcolordatamid[pixel_point] =pcolordata[original_point_a] * (1-distance_to_a_x) * (1-distance_to_a_y) +pColorData[ Original_point_b] * distance_to_a_x* (1-distance_to_a_y) +pcolordata[original_point_c] * distance_to_a_y* (1-distance _to_a_x) +pcolordata[original_point_c] * distance_to_a_y*distance_to_a_x;pcolordatamid[pixel_point + 1] =pColorData[  Original_point_a + 1] * (1-distance_to_a_x) * (1-distance_to_a_y) +pcolordata[original_point_b + 1] * distance_to_a_x* (1 -distance_to_a_y) +pcolordata[original_point_c + 1] * distance_to_a_y* (1-distance_to_a_x) +pColorData[original_point _c + 1] * distance_to_a_y*distance_to_a_x;pcolordatamid[pixel_point + 2] =pcolordata[original_point_a + 2] * (1-distance _to_a_x) * (1-distance_to_a_y) +pcolordata[original_point_b + 2] * distance_to_a_x* (1-distance_to_a_y) +pColorData[ Original_point_c + 2] * distance_to_a_y* (1-distance_to_a_x) +pcolordata[original_point_c + 2] * distance_to_a_y*distance_to_a_x;} /******************* image rotation ******************//******************* image Processing Section ******************/fwrite (PColorDataMid, 1   , Write_ndata, Wfile); The image data area will be processed back to file fclose (pfile), fclose (wfile);p rintf ("image processing complete \ n");p rintf ("Runtime:%dms\n", int ((double) (clock ()-now) )/clocks_per_sec * 1000));//Output image processing takes time information}

the original image and the resulting rotated image are as follows:


Original image


Post-rotation image







C + + BMP (24-bit true color) image processing (4)------Image rotation

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.