从网上找了一个CImage的旋转函数,但是好像在读取一些图片的时候会出错,
哪位大神知道问题出在哪里呢?
//------图像旋转
//参数:源图像 目标图像 旋转度(alpha = angle * 3.14 / 180)
//using method: CImage *dest = new CImage;ImageRotate(src,dest,alpha);
//算法:邻近点算法
void ImageRotate(CImage *Imgm, CImage *Imgn, double alpha)
{
int ww, Dx, Dy, bpd;
double centerx, centery, sintheta, costheta;
double X1, Y1, X2, Y2, theta, xx, yy, rr;
BYTE **list, *sc, *lp;
int x, y;
//Dx获取宽度
Dx=Imgm->GetWidth();
//Dy获取高度
Dy=Imgm->GetHeight();
sc=(BYTE*)malloc(2*(Dx*Imgm->GetBPP()+31)/32*4); //申请工作单元
list=(BYTE**)malloc(Dy*sizeof(BYTE*)); //对原位图建立二维数组
//list中保存的是每一个高度像素的地址
for (int i=0;i<Dy;i++)
{
list[i]=(BYTE*)Imgm->GetPixelAddress(0, i);
}
//计算位图中心位置
centerx=Dx/2.0+0.5;
centery=Dy/2.0+0.5;
//计算对角线长度
rr=sqrt(centerx*centerx+centery*centery);
//反正切
theta=atan(centery/centerx);
//求图像边缘长度
X1=fabs(rr*cos(alpha+theta))+0.5;
Y1=fabs(rr*sin(alpha+theta))+0.5;
X2=fabs(rr*cos(alpha-theta))+0.5;
Y2=fabs(rr*sin(alpha-theta))+0.5;
//得外接矩形宽度 哪条边长就用哪个长度
if (X2>X1)
X1 = X2;
//外接矩形高度
if (Y2>Y1)
Y1 = Y2;
//图片的像素值
ww=(int)(2 * X1);
Imgn->Destroy();
//建立结果位图
Imgn->Create(ww,(int)(2*Y1),Imgm->GetBPP());
bpd = Imgm->GetBPP()/8;
sintheta = sin(alpha);
costheta = cos(alpha);
for (int j=(int)(centery-Y1),Yd=0;j<=(centery + Y1);j++,Yd++)
{
//256色位图像素行置背景值
if (Imgm->GetBPP()==8)
memset(sc,255,ww);
//真彩色位图像素行置背景值
else
memset(sc,255,ww*bpd);
for (int i=(int)(centerx-X1),Xd=0;i<=centerx+X1;i++,Xd+=bpd)
{
xx=centerx+costheta*(i-centerx)+sintheta*(j-centery);
yy=centery-sintheta*(i-centerx)+costheta*(j-centery);
x=(int)(xx+0.5);
y=(int)(yy+0.5);
if (x<0||x>= Imgm->GetWidth()||y<0||y>=Imgm->GetHeight())
continue;
if(x==Imgm->GetWidth())
x--;
if(y==Imgm->GetHeight())
y--;
memcpy(&sc[Xd],&list[y][x*bpd],bpd); //从源位图复制像素数据
}
lp=(BYTE*)Imgn->GetPixelAddress(0,Yd); //处理结果总结果位图
memcpy(lp,sc,ww*bpd);
}
free(list); //释放工作单元
free(sc);
}
已知在读取某些bmp和png图像时函数会挂掉。。
这个函数的实现是使用邻近点算法进行图像旋转的,但这种算法可能会产生图像失真和锯齿状的边缘,因此建议使用更高级别的插值算法,如双线性插值或双立方插值算法。
至于为什么会在读取某些 BMP 和 PNG 图像时函数会挂掉,可能是因为该函数对于不同格式的图像数据可能存在一些兼容性问题。建议使用更专业的图像处理库或者工具来实现图像旋转操作,例如 OpenCV 库或者 ImageMagick 工具。
如果您仍然想继续使用这个函数,建议在调用该函数之前,先对图像进行格式转换,确保其格式与该函数所支持的格式相同。您可以使用 CImage 类的 Load
方法将图像加载到内存中,然后使用 GetBPP
方法获取像素位数,GetPitch
方法获取像素数据的行距,以及 GetPixelAddress
方法获取像素数据的地址,再将这些信息传递给 ImageRotate
函数进行图像旋转。同时,您也可以在调用该函数时,捕获异常来避免程序崩溃,例如:
try {
ImageRotate(&src, &dest, angle);
} catch (...) {
// 处理异常
}
不过这只是一种暂时的解决方案,建议还是使用更可靠的图像处理库或工具来进行图像旋转操作。