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

tiankong1399 2008-10-27 11:09:35
下面是我实现图像旋转的函数,运行时老出错,不同的输入值,有时出现不同的错误提示,一般提示: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);
}
...全文
676 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
net_gzj 2012-07-20
  • 打赏
  • 举报
回复
请问各位高手 为什么
if (ImageType(Imgm) == 2) flag = 1; //flag为标志位,当取值为1时,表示双线性内插法
这句话编译不通过
提示 error C2440: “<function-style-cast>”: 无法从“ATL::CImage”转换为“Gdiplus::ImageType”
caoyanjuan2 2012-07-12
  • 打赏
  • 举报
回复
struct IMAGEPARAMENT
{
int nWidth;
int nHeight;
int nBitCount;
int nBytesPerLine;
int nBytesPerPixel;
int nNumColors;
int nSize;
};
kingsuper68 2010-11-13
  • 打赏
  • 举报
回复
学习学习
zgxsdkjdx 2008-10-28
  • 打赏
  • 举报
回复
请问高手IMAGEPARAMENT是您自己设置的结构体么?
tiankong1399 2008-10-27
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 lfchen 的回复:]
不是90度,180度,270度的时候,修整的图像像素点超过了原来的点素了吧?数组溢出?
[/Quote]
可能是,我一直改,都不行。会的看看帮忙。
一条晚起的虫 2008-10-27
  • 打赏
  • 举报
回复
不是90度,180度,270度的时候,修整的图像像素点超过了原来的点素了吧?数组溢出?
tiankong1399 2008-10-27
  • 打赏
  • 举报
回复
楼上正解,,,谢谢了。
laoma_hbu 2008-10-27
  • 打赏
  • 举报
回复
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;
nSize = 0;
if (Dx < Dy)
{
nSize = Dy;
}
else
{
nSize = Dx;
}
int nLineBytes = (nSize * P.nBitCount + 31) / 32 * 4;

//还有一点要修改,不然当图像高度远大于宽度时会崩溃
sc = (BYTE*) malloc(2 * nLineBytes); // * 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);

}


再试试,呵呵。
laoma_hbu 2008-10-27
  • 打赏
  • 举报
回复
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);
}


tiankong1399 2008-10-27
  • 打赏
  • 举报
回复
GDI+没用过,不知道怎么用,惭愧~~
chenyu2202863 2008-10-27
  • 打赏
  • 举报
回复
怎么想到用CImageList类呢?

推荐使用GDI+来完成操作,然后你的问题内存益处,考虑容器如何~
tiankong1399 2008-10-27
  • 打赏
  • 举报
回复
能详细点吗,最好指出我代码中哪部分出错。
linglongyouzhi 2008-10-27
  • 打赏
  • 举报
回复
原坐标旋转后要判断一下是不是超出了的图像宽度、长度限制,超过的部分应该直接丢弃

19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧