原理参考:https://blog.csdn.net/liyuan02/article/details/6750828
实现对对任意角度的旋转,具体数学推导网上找。如果各位读者需要使用,只需要将打开文件的位置改为你的位置,输入不同的角度即可:
#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度
后续持续更新用C语言实现图像处理算法,敬请期待,欢迎关注。