我使用CDib类做位图图像处理,自己编了图像旋转,放大的函数,函数应该没有问题,因为处理后的结果图像显示正确,就是保存结果的时候出现问题,有时候保存不了,信息头中图像的宽高大小我都更改了,数据快部分也应该没有问题,毕竟可以正确显示。
   旋转90度,放大一倍(大小未变),都可以正常保存。
   想了很久也不知道怎么回事,哪位懂得的给点建议,谢谢

解决方案 »

  1.   

    你不用分配存储空间,用原来大小的就可以正常保存,但是用其他倍数的,就会错误。
    看看你保存的文件的大小,例如以bmp为例扩大4倍的大小应该是(a-54)x4+54,不是的话就是你的内存分配有问题。再用ultraedit看下对应的宽高是否正确。
      

  2.   

    谢谢一楼提示。内存分配如果有问题的话,处理后的图像为什么还能正确显示呢。
    内存分配是按照 newHeight*newWidth(4整倍数)分配的,8位图newimage=(LPBYTE) new char[newHeight*newWidth];
    ......
    delete lpimage;//释放原图像数据
    lpimage=newimage;
      

  3.   

    是你内存有错误。一象素点的颜色RGB一般占3个字节,24B,你只分配了1个,8B。
      

  4.   

    你需要把原始的每一个像素的值,重复放到放大之后的位置,因为放大了,所以你就要重复放上去,你放大多少倍,就要重复放上去多少个点
    同时,修改头中的高和宽,以及bmp的数据大小即可
      

  5.   

    //刚开始写代码,各位见笑
    void CImageShowView::OnXuanzhuan() 
    {
    // TODO: Add your command handler code here
    CImageShowDoc* pDoc = GetDocument();
    ASSERT_VALID(pDoc); LONG biwidth=pDoc->m_pDibInit->m_lpBMIH->biWidth;//原图像宽和高
    LONG biheight=pDoc->m_pDibInit->m_lpBMIH->biHeight;
    LONG bilinebytes; LONG newwidth=0;//新宽和高
    LONG newheight=0;
    LONG newlinebytes; float angle=90; //旋转角度
    double angle1=0;
    float sina=0;
    float cosa=0; float x1,y1,x2,y2,x3,y3,x4,y4;//原图像四个角坐标 
    float nx1,ny1,nx2,ny2,nx3,ny3,nx4,ny4;//新~~ LONG i,j;
    LONG i0,j0;//新坐标 float x,y; LPBYTE newimage=NULL;
    LPBYTE lpimage=NULL;
    LPBYTE a=NULL;//指向新图像象素
    LPBYTE b=NULL; if(pDoc->m_pDibInit->m_lpBMIH->biBitCount!=8)
    {
    MessageBox("目前只支持查看256色位图灰图!", "系统提示" , MB_ICONINFORMATION | MB_OK);
    return;
    } CDlgxuanzhuan dlg;
    dlg.m_angle=90;
    if(dlg.DoModal()!=IDOK)
    {
    return;
    }
    angle=dlg.m_angle;//获取输入角度
    delete dlg; bilinebytes=(biwidth*8+31)/32*4;
    angle1=(double)(angle*3.1415926*2/360);//弧度
    sina=(float)sin(angle1);
    cosa=(float)cos(angle1); //
    x1=y1=0;
    x2=biwidth-1;
    y2=0;
    x3=biwidth-1;
    y3=biheight-1;
    x4=0;
    y4=biheight-1; nx1=cosa*x1+sina*y1;
    ny1=-sina*x1+cosa*y1;
    nx2=cosa*x2+sina*y2;
    ny2=-sina*x2+cosa*y2;
    nx3=cosa*x3+sina*y3;
    ny3=-sina*x3+cosa*y3;
    nx4=cosa*x4+sina*y4;
    ny4=-sina*x4+cosa*y4; newwidth=(LONG)(max(fabs(nx1-nx3),fabs(nx4-nx2))+0.5); //新图像宽高
    newheight=(LONG)(max(fabs(ny1-ny3),fabs(ny4-ny2))+0.5);
    newlinebytes=(newwidth*8+31)/32*4;    //每行字节,4整数倍 x = (float) (-0.5 * (newwidth - 1) * cosa - 0.5 * (newheight - 1) * sina //两个常量
    + 0.5 * (biwidth  - 1));
    y = (float) ( 0.5 * (newwidth - 1) * sina - 0.5 * (newheight - 1) * cosa
    + 0.5 * (biheight - 1)); newimage = (LPBYTE) new char[newlinebytes*newheight];//新图像数据内存
    if(newimage==NULL)
    {
    MessageBox("内存分配失败", "系统提示" , MB_ICONINFORMATION | MB_OK);
    return;
    } lpimage=pDoc->m_pDibInit->m_lpImage;
    pDoc->m_pDibInit->m_lpBMIH->biWidth=newwidth;
    pDoc->m_pDibInit->m_lpBMIH->biHeight=newheight;
    pDoc->m_pDibInit->m_lpBMIH->biSizeImage=(DWORD)newheight*newlinebytes;
    //处理过程
    for(i0=0;i0<newheight;i0++)
    {
    for(j0=0;j0<newwidth;j0++)
    {
    a = newimage+ newlinebytes * (newheight - 1 - i0) + j0;
    i= (LONG) (-((float) j0) * sina + ((float) i0) * cosa + y + 0.5);
    j= (LONG) ( ((float) j0) * cosa + ((float) i0) * sina + x + 0.5);
    if((i>=0)&&(i<biheight)&&(j>=0)&&(j<biwidth))
    {
    b=lpimage + bilinebytes * (biheight - 1 - i) + j;
    *a=*b;
    }
    else
    {
    *a=255;
    }
    }
    }

    delete pDoc->m_pDibInit->m_lpImage;
    pDoc->m_pDibInit->m_lpImage=newimage;

    // 设置脏标记
    pDoc->SetModifiedFlag(TRUE); // 更新视图
    pDoc->UpdateAllViews(NULL);
    return;
    }
      

  6.   

    如果是旋转,就不需要修改bmp文件头了,你旋转后的大小没有改变,难道你改变了大小?
      

  7.   

    非常感谢各位的关注,问题已经解决.
    毛病不在处理过程的函数,还在最终保存的写函数write.
    write里面写图像数据块时file.write(m_lpImage,m_dwSizeImage);参数m_dwSizeImage是单独一个参数,大小等于信息头的biSizeImage,确需要另外修改,只记得修改后者,忘记前者了