首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

CImage图像旋转有关问题,自己修改不成功,会的帮忙修改上,多谢~·

2012-07-28 
CImage图像旋转问题,自己修改不成功,会的帮忙修改下,谢谢~~下面是我实现图像旋转的函数,运行时老出错,不同

CImage图像旋转问题,自己修改不成功,会的帮忙修改下,谢谢~~·
下面是我实现图像旋转的函数,运行时老出错,不同的输入值,有时出现不同的错误提示,一般提示:1.内存冲突 2.堆被损坏,或者系统存在bug  
然而,当输入值为1.57 3.14 6.28(也就是90度 180度 360度)时,程序可以实现图像旋转??
请大家帮忙看看是什么问题,,可以的话,帮忙修改看看,,程序如下::

inline void ImageRotate(CImage *Imgn,CImage *Imgm, double alpha)//任意角度旋转图片
{
struct IMAGEPARAMENT P;
RGBQUAD ColorTab[256];
int i, j, ww, Xd, Yd, Dx, Dy,nSize;
double centerx, centery, sintheta, costheta;
double X1, Y1, X2, Y2, theta, xx, yy, rr;
BYTE **list, *sc;
int x1, y1, x2, y2, flag;
double p, q, a, b, c, d, t1, t2, t3;

if (ImageType(Imgm) == 2) flag = 1;//flag为标志位,当取值为1时,表示双线性内插法
else flag = 0;//0表示最近邻点法
GetImageParament(Imgm, &P);
Dx = P.nWidth;
Dy = P.nHeight;
sc = (BYTE*) malloc(2 * P.nBytesPerLine);//申请工作单元
list = (BYTE**) malloc(Dy * sizeof(BYTE*));//对原位图建立二维数组
for (i = 0; i < Dy; i++)
list[i] = (BYTE*) Imgm ->GetPixelAddress(0, i);
centerx = Dx / 2;//计算位图中心位置
centery = Dy / 2;
rr = sqrt(centerx * centerx + centery *centery);//计算对角线长度
theta = atan((double) centery / (double) 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), P.nBitCount );//建立结果位图
if (P.nBitCount == 8)
{
GetAllPalette(Imgm, ColorTab);
SetAllPalette(Imgm, ColorTab);//复制调色板
}
sintheta = sin(alpha);
costheta = cos(alpha);

for (j = (int) (centery - Y1), Yd = 0; j <= (centery + Y1); j++, Yd++)
{
if (P.nBitCount == 8)
memset (sc, 0, ww);//256色位图像素行置背景值
else
memset(sc, 0, ww * P.nBytesPerPixel);//真彩色位图像素行置背景值
for (i = (int) (centerx - X1), Xd = 0; i <= centerx + X1; i++, Xd += P.nBytesPerPixel)
{
xx = centerx + costheta * (i - centerx) + sintheta * (j - centery);
yy = centery - sintheta * (i - centerx) + costheta * (j - centery);
x1 = (int) xx;
x2 = x1 + 1;
p = xx - x1;
y1 = (int) yy;
y2 = y1 + 1;
q = yy - y1;
if (((x1 < 0)||(x2 >= P.nWidth )||(y1 < 0)||(y2 >= P.nHeight )))
continue;
if (flag == 0)
{
if (q > 0.5) y1 = y2;
if (p > 0.5) x1 = x2;
memcpy(&sc[i * P.nBytesPerPixel], &list[y1][x1 * P.nBytesPerPixel],P.nBytesPerPixel);//从源位图复制像素数据
}
else
{// flag等于1,双线性内插法
a = (double) list[y1][x1];//从源位图取数据
b = (double) list[y1][x2];
c = (double) list[y2][x1];
d = (double) list[y2][x2];
t1 = (1 - p) * a + p * b;//双线性内插计算
t2 = (1 - p) * c + p * d;
t3 = (1 - q) * t1 + q * t2;
sc[i] = (BYTE) t3;
}
}
SetRectValue(Imgn, 0, Yd, ww, 1, sc);
}
free(list);//释放工作单元
free(sc);
}

[解决办法]
不是90度,180度,270度的时候,修整的图像像素点超过了原来的点素了吧?数组溢出?
[解决办法]
原坐标旋转后要判断一下是不是超出了的图像宽度、长度限制,超过的部分应该直接丢弃
[解决办法]
怎么想到用CImageList类呢?

推荐使用GDI+来完成操作,然后你的问题内存益处,考虑容器如何~

[解决办法]

C/C++ code
void ImageRotation(CImage *Imgn, CImage *Imgm, double alpha){    struct IMAGEPARAMENT P;     RGBQUAD ColorTab[256];     int i, j, ww, Xd, Yd, Dx, Dy,nSize;     double centerx, centery, sintheta, costheta;     double X1, Y1, X2, Y2, theta, xx, yy, rr;     BYTE **list, *sc;     int x1, y1, x2, y2, flag;     double p, q, a, b, c, d, t1, t2, t3;         if (ImageType(Imgm) == 2)  flag = 1; //flag为标志位,当取值为1时,表示双线性内插法     else flag = 0; //0表示最近邻点法     GetImageParament(Imgm, &P);     Dx = P.nWidth;     Dy = P.nHeight;     sc = (BYTE*) malloc(2 * P.nBytesPerLine); //申请工作单元     list = (BYTE**) malloc(Dy * sizeof(BYTE*)); //对原位图建立二维数组     for (i = 0; i < Dy; i++)         list[i] = (BYTE*)  Imgm ->GetPixelAddress(0, i);     centerx = Dx / 2; //计算位图中心位置     centery = Dy / 2;     rr = sqrt(centerx * centerx + centery *centery); //计算对角线长度     theta = atan((double) centery / (double) 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), P.nBitCount ); //建立结果位图     if (P.nBitCount == 8)     {         GetAllPalette(Imgm, ColorTab);         //修改一,设置目标调色板        SetAllPalette(Imgn, ColorTab); //复制调色板     }     sintheta = sin(alpha);     costheta = cos(alpha);         for (j = (int) (centery - Y1), Yd = 0; j <= (centery + Y1); j++, Yd++)     {         if (P.nBitCount == 8)             memset (sc, 0, ww); //256色位图像素行置背景值         else             memset(sc, 0, ww * P.nBytesPerPixel); //真彩色位图像素行置背景值         for (i = (int) (centerx - X1), Xd = 0; i <= centerx + X1; i++, Xd += P.nBytesPerPixel)         {             xx = centerx + costheta * (i - centerx) + sintheta * (j - centery);             yy = centery - sintheta * (i - centerx) + costheta * (j - centery);             x1 = (int) xx;             x2 = x1 + 1;             p = xx - x1;             y1 = (int) yy;             y2 = y1 + 1;             q = yy - y1;             if (((x1 < 0)||(x2 >= P.nWidth )||(y1 < 0)||(y2 >= P.nHeight )))                 continue;             if (flag == 0)             {                 if (q > 0.5)  y1 = y2;                 if (p > 0.5)  x1 = x2;                 //修改二, sc[Xd]                memcpy(&sc[Xd], &list[y1][x1 * P.nBytesPerPixel], P.nBytesPerPixel); //从源位图复制像素数据             }             else             { // flag等于1,双线性内插法                 a = (double) list[y1][x1]; //从源位图取数据                 b = (double) list[y1][x2];                 c = (double) list[y2][x1];                 d = (double) list[y2][x2];                 t1 = (1 - p) * a + p * b; //双线性内插计算                 t2 = (1 - p) * c + p * d;                 t3 = (1 - q) * t1 + q * t2;                 //修改三                sc[Xd] = (BYTE) t3;             }         }         SetRectValue(Imgn, 0, Yd, ww, 1, sc);     }     free(list); //释放工作单元     free(sc); } 

热点排行