C語言實現BMP影象旋轉(任意角度)
阿新 • • 發佈:2018-12-08
實現對對任意角度的旋轉,具體數學推導網上找。如果各位讀者需要使用,只需要將開啟檔案的位置改為你的位置,輸入不同的角度即可:
#include <Windows.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #define CV_PI 3.1415926 int main(){ FILE *fp = fopen("./01.bmp", "rb"); if (fp == 0){ printf("檔案開啟失敗\n"); return 0; } BITMAPFILEHEADER fileHead; BITMAPINFOHEADER infoHead; fread(&fileHead, sizeof(BITMAPFILEHEADER), 1, fp); fread(&infoHead, sizeof(BITMAPINFOHEADER), 1, fp); int width = infoHead.biWidth; int height = infoHead.biHeight; int biCount = infoHead.biBitCount; int lineByte = (width*biCount / 8 + 3) / 4 * 4; RGBQUAD *pColorTable; pColorTable = new RGBQUAD[256]; fread(pColorTable, sizeof(RGBQUAD), 256, fp); unsigned char *pBmpBufSrc,*pBmpBufDst; pBmpBufSrc = new unsigned char[lineByte*height]; fread(pBmpBufSrc, lineByte*height, 1, fp); fclose(fp); double angle; printf("請輸入需要旋轉的角度: "); scanf("%lf", &angle); double sita = angle*CV_PI / 180; double a = (width - 1) / 2; double b = (height - 1) / 2; double x1 = -a*cos(sita) - b*sin(sita); double y1 = -a*sin(sita) + b*cos(sita); double x2 = a*cos(sita) - b*sin(sita); double y2 = a*sin(sita) + b*cos(sita); double x3 = a*cos(sita) + b*sin(sita); double y3 = a*sin(sita) - b*cos(sita); double x4 = -a*cos(sita) + b*sin(sita); double y4 = -a*sin(sita) - b*cos(sita); int w1 = round(fmax(abs(x1 - x3), abs(x2 - x4))); int h1 = round(fmax(abs(y1 - y3), abs(y2 - y4))); double c = (w1 - 1) / 2; double d = (h1 - 1) / 2; double f1 = -c*cos(sita) + d*sin(sita) + a; double f2 = -c*sin(sita) - d*cos(sita) + b; int lineByte1 = (w1*biCount / 8 + 3) / 4 * 4; pBmpBufDst = new unsigned char[lineByte1*h1]; for (int i = 0; i < h1; ++i){ for (int j = 0; j < w1; ++j){ unsigned char *p; p = (unsigned char *)(pBmpBufDst + i*lineByte1 + j); (*p) = 255; } } for (int i = 0; i < h1; ++i){ for (int j = 0; j < w1; ++j){ int x = round(j*cos(sita) - i*sin(sita) + f1); int y = round(j*sin(sita) + i*cos(sita) + f2); if (x>0 && x<width && y>0 && y < height){ unsigned char *p1, *p2; p1 = (unsigned char *)(pBmpBufDst + i*lineByte1 + j); // 新影象 p2 = (unsigned char *)(pBmpBufSrc + y*lineByte + x); // 原影象 (*p1) = (*p2); } } continue; } char *DstName = "rotate.bmp"; FILE *fpo = fopen(DstName, "wb"); if (fpo == 0) return 0; int colorTableSize = 0; if (biCount == 8) colorTableSize = 1024; BITMAPFILEHEADER dstFileHead; dstFileHead.bfOffBits = 14 + 40 + colorTableSize; dstFileHead.bfReserved1 = 0; dstFileHead.bfReserved2 = 0; dstFileHead.bfSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+colorTableSize + lineByte1*h1; dstFileHead.bfType = 0x4D42; fwrite(&dstFileHead, sizeof(dstFileHead), 1, fpo); BITMAPINFOHEADER dstInfoHead; dstInfoHead.biBitCount = biCount; dstInfoHead.biClrImportant = 0; dstInfoHead.biClrUsed = 0; dstInfoHead.biCompression = 0; dstInfoHead.biHeight = h1; dstInfoHead.biPlanes = 1; dstInfoHead.biSize = 40; dstInfoHead.biSizeImage = lineByte1*h1; dstInfoHead.biWidth = w1; dstInfoHead.biXPelsPerMeter = 0; dstInfoHead.biYPelsPerMeter = 0; fwrite(&dstInfoHead, sizeof(BITMAPINFOHEADER), 1, fpo); fwrite(pColorTable, sizeof(RGBQUAD), 256, fpo); fwrite(pBmpBufDst, lineByte1*h1, 1, fpo); fclose(fpo); system("pause"); return 1; }
原圖 右旋轉30度 右旋轉45 右旋轉60度 右旋轉90度