qq_27999103 2017-07-07 09:21 采纳率: 0%
浏览 650

C++ ImageRotate的一些问题

从网上找了一个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图像时函数会挂掉。。

  • 写回答

1条回答 默认 最新

  • 憧憬blog 2023-06-27 09:48
    关注

    这个函数的实现是使用邻近点算法进行图像旋转的,但这种算法可能会产生图像失真和锯齿状的边缘,因此建议使用更高级别的插值算法,如双线性插值或双立方插值算法。

    至于为什么会在读取某些 BMP 和 PNG 图像时函数会挂掉,可能是因为该函数对于不同格式的图像数据可能存在一些兼容性问题。建议使用更专业的图像处理库或者工具来实现图像旋转操作,例如 OpenCV 库或者 ImageMagick 工具。

    如果您仍然想继续使用这个函数,建议在调用该函数之前,先对图像进行格式转换,确保其格式与该函数所支持的格式相同。您可以使用 CImage 类的 Load 方法将图像加载到内存中,然后使用 GetBPP 方法获取像素位数,GetPitch 方法获取像素数据的行距,以及 GetPixelAddress 方法获取像素数据的地址,再将这些信息传递给 ImageRotate 函数进行图像旋转。同时,您也可以在调用该函数时,捕获异常来避免程序崩溃,例如:

    try {
        ImageRotate(&src, &dest, angle);
    } catch (...) {
        // 处理异常
    }
    

    不过这只是一种暂时的解决方案,建议还是使用更可靠的图像处理库或工具来进行图像旋转操作。

    评论

报告相同问题?

悬赏问题

  • ¥20 蓝牙耳机怎么查看日志
  • ¥15 Fluent齿轮搅油
  • ¥15 八爪鱼爬数据为什么自己停了
  • ¥15 交替优化波束形成和ris反射角使保密速率最大化
  • ¥15 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏