#include <windows.h>
#include <iostream>
#include <math.h>
#include <stdlib.h>
#include "simpleDIB.h"
#define pi 3.1415926535
using namespace std;
//=============================图像旋转处理函数================================
unsigned char* rotate_process(unsigned char*odd_Pdata,long &width,long &height,int biBitCount,float angle)
{
int new_width,new_height;//定义新图像的宽、高
float odd_x1,odd_y1,odd_x2,odd_y2,odd_x3,odd_y3,odd_x4,odd_y4;//定义原图像坐标
float new_x1,new_y1,new_x2,new_y2,new_x3,new_y3,new_x4,new_y4;//定义新图像坐标
float sina,cosa,temp1,temp2,alpha;//定义中间参数
alpha=pi*angle/180;//角度转换
cosa=float(cos(double(alpha)));//计算中间参数
sina=float(sin(double(alpha)));
odd_x1=float(-0.5*width);odd_y1=float(0.5*height);//计算旧图像坐标,为转换做准备
odd_x2=float(0.5*width);odd_y2=odd_y1;
odd_x3=odd_x1;odd_y3=float(-0.5*height);
odd_x4=odd_x2;odd_y4=odd_y3;
new_x1=cosa*odd_x1+sina*odd_y1;//新坐标的计算
new_y1=-sina*odd_x1+cosa*odd_y1;
new_x2=cosa*odd_x2+sina*odd_y2;
new_y2=-sina*odd_x2+cosa*odd_y2;
new_x3=cosa*odd_x3+sina*odd_y3;
new_y3=-sina*odd_x3+cosa*odd_y3;
new_x4=cosa*odd_x4+sina*odd_y4;
new_y4=-sina*odd_x4+cosa*odd_y4;
float t1=fabs(new_x4-new_x1);//获取新图像宽、高用于更新头文件信息
float t2=fabs(new_x3-new_x2);
new_width=int(t1>t2?t1:t2);
t1=fabs(new_y4-new_y1);
t2=fabs(new_y3-new_y2);
new_height=int(t1>t2?t1:t2);
temp1=float(-0.5*new_width*cosa+0.5*new_height*sina+0.5*width);//中间变量,实现逆变换的需要
temp2=float(-0.5*new_width*sina-0.5*new_height*cosa+0.5*height);
int lineByte=(width*biBitCount/8+3)/4*4;//确保每行数据为4的倍数,便于存取
int lineByte2=(new_width*biBitCount/8+3)/4*4 ;
unsigned char* new_Pdata;
new_Pdata=new unsigned char[lineByte2*new_height];//开辟新的空间,存放处理后的图像。
memset(new_Pdata,0,lineByte2*new_height);
int x,y,x0,y0;
for(y=0;y<new_height;y++)
for(x=0;x<new_width;x++)
{
x0=int(x*cosa-y*sina+temp1);
y0=int(x*sina+y*cosa+temp2);
if(biBitCount==8)
{
if ((x0>=0)&&(x0<width)&&(y0>=0)&&(y0<height))
*(new_Pdata+lineByte2*y+x)=*(odd_Pdata+lineByte*y0+x0); //坐标更新
else
*(new_Pdata+lineByte2*y+x)=255;//超出范围则将画布定为白色
}
if(biBitCount==24)
{
if ((x0>=0)&&(x0<width)&&(y0>=0)&&(y0<height))
{ *(new_Pdata+lineByte2*y+x*3)=*(odd_Pdata+lineByte*y0+x0*3);//坐标更新
*(new_Pdata+lineByte2*y+x*3+1)=*(odd_Pdata+lineByte*y0+x0*3+1);
*(new_Pdata+lineByte2*y+x*3+2)=*(odd_Pdata+lineByte*y0+x0*3+2);
}
else
{
*(new_Pdata+lineByte2*y+x*3)=255;//超出范围则将画布定为白色
*(new_Pdata+lineByte2*y+x*3+1)=255;
*(new_Pdata+lineByte2*y+x*3+2)=255;
}
}
}
width=new_width;//更新头文件有关信息
height=new_height;
delete[] odd_Pdata;//扫尾处理,释放内存空间
return new_Pdata;
}
//=====================================================================================
void main()
{
SimpleDIB dib;
if(!dib.ReadDIB("1.bmp"))
{
cout<<"read file error!\n";
return;
}
int receive;
cout<<"请输入需要旋转的角度:"<<endl;
cin>>receive;
dib.pData=rotate_process(dib.pData,dib.pbih->biWidth,dib.pbih->biHeight,dib.pbih->biBitCount,receive);
BYTE* pData=new BYTE[dib.pbih->biWidth*dib.pbih->biBitCount/8*dib.pbih->biHeight];
int lwidth = dib.widthAlign(dib.pbih->biWidth,dib.pbih->biBitCount);
int width = dib.pbih->biWidth*dib.pbih->biBitCount/8;
for(int y=0;y<dib.pbih->biHeight;y++)
{
memcpy(pData+width*y,dib.pData+lwidth*y,width);
}
dib.WriteDIB("旋转处理1.bmp",pData,dib.pbih->biBitCount,dib.pbih->biWidth,dib.pbih->biHeight);
delete[] pData;
cout<<"旋转处理完成1,请查看!\n";
if(!dib.ReadDIB("2.bmp"))
{
cout<<"read file error!\n";
return;
}
cout<<"请输入需要旋转的角度:"<<endl;
cin>>receive;
dib.pData=rotate_process(dib.pData,dib.pbih->biWidth,dib.pbih->biHeight,dib.pbih->biBitCount,receive);
pData=new BYTE[dib.pbih->biWidth*dib.pbih->biBitCount/8*dib.pbih->biHeight];
lwidth = dib.widthAlign(dib.pbih->biWidth,dib.pbih->biBitCount);
width = dib.pbih->biWidth*dib.pbih->biBitCount/8;
for(y=0;y<dib.pbih->biHeight;y++)
{
memcpy(pData+width*y,dib.pData+lwidth*y,width);
}
dib.WriteDIB("旋转处理2.bmp",pData,dib.pbih->biBitCount,dib.pbih->biWidth,dib.pbih->biHeight);
delete[] pData;
cout<<"旋转处理完成2,请查看!\n";
}