C语言实现BMP图像处理(任意角度旋转)

原理参考: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语言实现图像处理算法,敬请期待,欢迎关注。

  • 12
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 25
    评论
评论 25
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值