19,468
社区成员
发帖
与我相关
我的任务
分享
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);
}
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);
}