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); }