There are a lot of information about bitmap rotation on the Internet, but I don't know much about it (I didn't look it up). So I also wrote one, hoping to help beginners like me.
Step 1: You must know the structure of the bitmap (BMP) format file.
A Bitmap (bmp) file consists of the following parts:
1. BITMAPFILEHEADER, which is defined as follows:
Typedef struct tagBITMAPFILEHEADER {
WORD bfType; // The value must be 'bm'
DWORD bfSize; // File Size
WORD bfReserved1; // It must be 0
WORD bfReserved2; // It must be 0
DWORD bfOffBits; // offset from ITMAPFILEHEADER to stored bmp data
} BITMAPFILEHEADER, * PBITMAPFILEHEADER;
2. BITMAPINFOHEADER, which is defined as follows:
Typedef struct tagBITMAPINFOHEADER {
DWORD biSize; // the size of this structure, which can be obtained by sizeof (BITMAPINFOHEAER ).
LONG biWidth; // The bitmap width, in pixels.
LONG biHeight; // bitmap height, in pixels
WORD biPlanes; // It must be 1
WORD biBitCount; // Number of Bitmap pixels, which can be 0, 1, 4, 8, 24, 32
DWORD biCompression;
DWORD biSizeImage; // (for compression only)
LONG biXPelsPerMeter; // a prime number of one-meter horizontal Image
LONG biYPelsPerMeter; // The Prime Number of the portrait of One Meter
DWORD biClrUsed; // (non-zero short color table)
DWORD biClrImportant;
} BITMAPINFOHEADER, * PBITMAPINFOHEADER;
As the above information can be found directly on MSDN, you can only make a brief introduction. You can view NSDN help on your own, which has a detailed introduction.
3. DIB-bit images. The real bitmap data is stored here.
Knowing the storage format of bitmap, we can easily read it as memory.
Step 2: Read the bmp Image
LPCTSTR lpszFileName4=untitled.bmp; // file path
CFile file; // used to read BMP files
BITMAPFILEHEADER bfhHeader; // bmp File Header
BITMAPINFOHEADER bmiHeader; // bmp format Header
LPBITMAPINFO lpBitmapInfo; // bmp format details
Int BMP width = 0; // Image Width
Int bmpHeight = 0; // Image Height
If (! File. Open (lpszFileName, CFile: modeRead ))
Return; // open the file
File. Read (& bfhHeader, sizeof (BITMAPFILEHEADER); // Read the file header
If (bfhHeader. bfType! = (WORD) ('M' <8) | 'B') // determines whether the parameter is BM.
Return;
If (bfhHeader. bfSize! = File. GetLength ())
Return;
If (file. Read (LPSTR) & bmiHeader, sizeof (bmiHeader ))! = Sizeof (bmiHeader ))
Return;
BmpHeight = bmiHeader. biHeight; // obtain the height and width.
BMP width = bmiHeader. biWidth;
File. SeekToBegin ();
File. Read (& bfhHeader, sizeof (BITMAPFILEHEADER ));
UINT uBmpInfoLen = (UINT) bfhHeader. bfOffBits-sizeof (BITMAPFILEHEADER );
LpBitmapInfo = (LPBITMAPINFO) new BYTE [uBmpInfoLen];
File. Read (LPVOID) lpBitmapInfo, uBmpInfoLen );
If (* (LPDWORD) (lpBitmapInfo ))! = Sizeof (BITMAPINFOHEADER ))
Return;
DWORD dwBitlen = bfhHeader. bfSize-bfhHeader. bfOffBits;
LPVOID lpSrcBits = new BYTE [dwBitlen]; // read data into the lpSrcBits Array
File. ReadHuge (lpSrcBits, dwBitlen );
File. Close (); // Close the file
Next we will display the image on the screen:
Step 3: display images
CClientDC hDC (this );
StretchDIBits (hDC, BMP width, bmpHeight, BMP width, bmpHeight,
LpSrcBits, lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY );
Step 4: read images into the memory device Environment
HDC dcSrc;
HBITMAP bitmap;
DcSrc = CreateCompatibleDC (hDC); // obtain a memory device Environment
Bitmap = CreateCompatibleBitmap (hDC, BMP width, bmpHeight );
SelectObject (dcSrc, bitmap );
BitBlt (dcSrc, BMP width, bmpHeight, hDC, SRCCOPY); // this step is very important
Step 5: Implement bitmap Rotation
Let's assume that the original form of the function for rotating bitmap is as follows:
Void RotateBitmap (HDC dcSrc, int SrcWidth, int SrcHeight, double angle, HDC pDC );
/* The parameters are described as follows: //////////////////////////////////////// /////////////////////////////////////
HDC dcSrc: memory device environment of the bitmap to be rotated, which is created in Step 4
Int SrcWidth: the width of the bitmap to be rotated.
Int SrcHeight: the height of the bitmap to be rotated
Double angle: angle of rotation, in radians
HDC pDC: The current screen device environment obtained in step 3
*/////////////////////////////////////// //////////////////////////////////////// ////////////////////////
// The following are the implementation details of the function.
Void RotateAnyAngle (HDC dcSrc, int SrcWidth, int SrcHeight, double angle)
{
Double x1, x2, x3;
Double y1, y2, y3;
Double maxWidth, maxHeight, minWidth, minHeight;
Double srcX, srcY;
Double sinA, cosA;
Double DstWidth;
Double DstHeight;
HDC dcDst; // memory device environment after rotation
HBITMAP newBitmap;
SinA = sin (angle );
CosA = cos (angle );
X1 =-SrcHeight * sinA;
Y1 = SrcHeight * cosA;
X2 = SrcWidth * cosA-SrcHeight * sinA;
Y2 = SrcHeight * cosA SrcWidth * sinA;
X3 = SrcWidth * cosA;
Y3 = SrcWidth * sinA;
MinWidth = x3> (x1> x2? X2: x1 )? (X1> x2? X2: x1): x3;
MinWidth = minWidth> 0? 0: minWidth;
MinHeight = y3> (y1> y2? Y2: y1 )? (Y1> y2? Y2: y1): y3;
MinHeight = minHeight> 0? 0: minHeight;
MaxWidth = x3> (x1> x2? X1: x2 )? X3 :( x1> x2? X1: x2 );
MaxWidth = maxWidth> 0? MaxWidth: 0;
MaxHeight = y3> (y1> y2? Y1: y2 )? Y3 :( y1> y2? Y1: y2 );
MaxHeight = maxHeight> 0? MaxHeight: 0;
DstWidth = maxWidth-minWidth;
DstHeight = maxHeight-minHeight;
DcDst = CreateCompatibleDC (dcSrc );
NewBitmap = CreateCompatibleBitmap (dcSrc, (int) DstWidth, (int) DstHeight );
SelectObject (dcDst, newBitmap );
For (int I = 0; I <DstHeight; I)
{
For (int J = 0; J <DstWidth; J)
{
SrcX = (J minWidth) * cosA (I minHeight) * sinA;
SrcY = (I minHeight) * cosA-(J minWidth) * sinA;
If (srcX> = 0) & (srcX <= SrcWidth) & (srcY> = 0) & (srcY <= SrcHeight ))
{
BitBlt (dcDst, J, I, 1, 1, dcSrc, (int) srcX, (int) srcY, SRCCOPY );
}
}
}
// Display the rotated bitmap
BitBlt (hDC, 200,200, (int) DstWidth, (int) DstHeight, dcDst, SRCCOPY );
DeleteObject (newBitmap );
DeleteDC (dcDst );
}
Finally, we can call it:
Double angle = (45/180. 0) * 3.14159; // rotate 45 Degree for any angle
RotateAnyAngle (dcSrc, BMP width, bmpHeight, angle ,);
This is a success.