作者:金海建
目的:在Windows Mobile上,微软的API和库不支持图片的任意角度旋转,只支持90,180,270度旋转。既然它不支持我们只能自力更生了。
简介:通过介绍和实现旋转PNG图片,来说明实现图片旋转的方法。过程大概如下,先用Imaging读取并解码png图片,使之转成ARGB格式的位图。然后利用顶点旋转的公式,对位图矩阵进行旋转,旋转完成后,利用Imaging库,转换成IImage接口。最后利用IImage接口来画图。
先来看下平面直角坐标变换的旋转坐标变换,其定义是
定义:若二坐标系{O;i,j}和{O′;i′,j′}满足O≡O′,另∠(i,j′)=θ
则坐标系{O′;i′,j′}可看成是由坐标系{O;i,j}绕O旋转θ角得到的,称由{O;i,j}到{O′;i′,j′}的变换为旋转坐标变换。
旋转公式为:
X' = X cosθ - Y sinθ
Y' = X sinθ + Y cosθ
由于我们是用数组的下表来表示坐标的,所以最小的坐标是为(0,0)。我们需要先做坐标旋转,然后平移坐标。如下图所示:
平移的动作,是把所以的负坐标变成正坐标。用MinX和MinY来表示最小的X坐标和Y坐标。
X' = X cosθ - Y sinθ - MinX;
Y' = X sinθ + Y cosθ - MinY;
根据上面的公式我们推出
x = (x'+MinX)cosθ+ (y'+MinY)sinθ
y = (y'+MinY)conθ- (x'+MinX)sinθ
图片旋转后,会出现失真现象,需要用双线性内插值进行优化
双线性内插值:对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v),其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值 f(i+u,j+v) 可由原图像中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,即:
f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。
这就是双线性内插值法。双线性内插值法计算量大,但缩放后图像质量高,不会出现像素值不连续的的情况。由于双线性插值具有低通滤波器的性质,使高频分量受损,所以可能会使图像轮廓在一定程度上变得模糊。
旋转代码
view plaincopy to clipboardprint?
void RotateImageBuf(const BYTE* src, int srcWidth, int srcHeight, BYTE*& dst, int& dstWidth, int& dstHeight, double angle)
{
double cosA = cos(angle);
double sinA = sin(angle);
double x1 = srcWidth * cosA;
double y1 = srcWidth * sinA;
double x2 = srcWidth * cosA - srcHeight * sinA;
double y2 = srcWidth * sinA + srcHeight * cosA;
double x3 = - srcHeight * sinA;
double y3 = srcHeight * cosA;
double minWidth = min(0,min(x3,min(x1,x2)));
double minHeight = min(0,min(y3,min(y1,y2)));
double maxWidth = max(0,max(x3,max(x1,x2)));
double maxHeight = max(0,max(y3,max(y1,y2)));
dstWidth = abs(maxWidth - minWidth) + 1;
dstHeight = abs(maxHeight - minHeight) + 1;
double ndstX = 0;
double ndstY = 0;
dst = new BYTE[dstWidth * dstHeight * 4];
UINT32 *pDst = (UINT32 *)dst;
UINT32 *pSrc = (UINT32 *)src;
UINT32 crDefault = ((UINT32 *)src)[0];
UINT32 color [2][2];
BYTE alpha[2][2];
BYTE rColor[2][2];
BYTE gColor[2][2];
BYTE bColor[2][2];
BYTE afinal,rfinal,gfinal,bfinal;
double ox,oy;
for(int y=0; y < dstHeight; y++)
{
for(int x=0; x < dstWidth; x++)
{
ndstX = (x + minWidth) * cosA + (y + minHeight) * sinA;
ndstY = (y + minHeight) * cosA - (x +minWidth) * sinA;
if((ndstX >= 0) && (ndstX < srcWidth) && (ndstY >= 0) && (ndstY < srcHeight))
{
color[0][0] = pSrc[ (int)((int)ndstY*srcWidth + ndstX) ];
if((int)ndstX + 1 >= srcWidth)
color[1][0] = crDefault;
else
color[1][0] = pSrc[ (int)((int)ndstY*srcWidth + ndstX +1) ];
if((int)ndstY + 1 >= srcHeight)
color[0][1] = crDefault;
else
color[0][1] = pSrc[ (int)(((int)ndstY+1)*srcWidth + ndstX) ];
if((int)ndstY + 1 >= srcHeight || (int)ndstX + 1 >= srcWidth)
color[1][1] = crDefault;
else
color[1][1] = pSrc[ (int)(((int)ndstY+1)*srcWidth + ndstX+1) ];
alpha[0][0] = (color[0][0] & 0XFF000000) >> 24;
bColor[0][0] = (color[0][0] & 0XFF0000) >> 16;
gColor[0][0] = (color[0][0] & 0X00FF00) >> 8;
rColor[0][0] = color[0][0] & 0X0000FF;
alpha[1][0] = (color[1][0] & 0XFF000000) >> 24;
bColor[1][0] = (color[1][0] & 0XFF0000) >> 16;
gColor[1][0] = (color[1][0] & 0X00FF00) >> 8;
rColor[1][0] = color[1][0] & 0X0000FF;
alpha[0][1] = (color[0][1] & 0XFF000000) >> 24;
bColor[0][1] = (color[0][1] & 0XFF0000) >> 16;
gColor[0][1] = (color[0][1] & 0X00FF00) >> 8;
rColor[0][1] = color[0][1] & 0X0000FF;
alpha[1][1] = (color[1][1] & 0XFF000000) >> 24;
bColor[1][1] = (color[1][1] & 0XFF0000) >> 16;
gColor[1][1] = (color[1][1] & 0X00FF00) >> 8;
rColor[1][1] = color[1][1] & 0X0000FF;
//f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
ox = (ndstX - (int)ndstX);
oy = (ndstY - (int)ndstY);
rfinal = (1 - ox)*(1 - oy)*rColor[0][0] + ox*(1 - oy)*rColor[1][0] + (1-ox)*oy*rColor[0][1] + ox*oy*rColor[1][1];
gfinal = (1 - ox)*(1 - oy)*gColor[0][0] + ox*(1 - oy)*gColor[1][0] + (1-ox)*oy*gColor[0][1] + ox*oy*gColor[1][1];
bfinal = (1 - ox)*(1 - oy)*bColor[0][0] + ox*(1 - oy)*bColor[1][0] + (1-ox)*oy*bColor[0][1] + ox*oy*bColor[1][1];
afinal = (1 - ox)*(1 - oy)*alpha[0][0] + ox*(1 - oy)*alpha[1][0] + (1-ox)*oy*alpha[0][1] + ox*oy*alpha[1][1];
pDst[y * (int)dstWidth + x] = RGBA(rfinal,gfinal,bfinal,afinal);
}
else
{
pDst[y * (int)dstWidth + x] = crDefault;
}
}
}
}
void RotateImageBuf(const BYTE* src, int srcWidth, int srcHeight, BYTE*& dst, int& dstWidth, int& dstHeight, double angle)
{
double cosA = cos(angle);
double sinA = sin(angle);
double x1 = srcWidth * cosA;
double y1 = srcWidth * sinA;
double x2 = srcWidth * cosA - srcHeight * sinA;
double y2 = srcWidth * sinA + srcHeight * cosA;
double x3 = - srcHeight * sinA;
double y3 = srcHeight * cosA;
double minWidth = min(0,min(x3,min(x1,x2)));
double minHeight = min(0,min(y3,min(y1,y2)));
double maxWidth = max(0,max(x3,max(x1,x2)));
double maxHeight = max(0,max(y3,max(y1,y2)));
dstWidth = abs(maxWidth - minWidth) + 1;
dstHeight = abs(maxHeight - minHeight) + 1;
double ndstX = 0;
double ndstY = 0;
dst = new BYTE[dstWidth * dstHeight * 4];
UINT32 *pDst = (UINT32 *)dst;
UINT32 *pSrc = (UINT32 *)src;
UINT32 crDefault = ((UINT32 *)src)[0];
UINT32 color [2][2];
BYTE alpha[2][2];
BYTE rColor[2][2];
BYTE gColor[2][2];
BYTE bColor[2][2];
BYTE afinal,rfinal,gfinal,bfinal;
double ox,oy;
for(int y=0; y < dstHeight; y++)
{
for(int x=0; x < dstWidth; x++)
{
ndstX = (x + minWidth) * cosA + (y + minHeight) * sinA;
ndstY = (y + minHeight) * cosA - (x +minWidth) * sinA;
if((ndstX >= 0) && (ndstX < srcWidth) && (ndstY >= 0) && (ndstY < srcHeight))
{
color[0][0] = pSrc[ (int)((int)ndstY*srcWidth + ndstX) ];
if((int)ndstX + 1 >= srcWidth)
color[1][0] = crDefault;
else
color[1][0] = pSrc[ (int)((int)ndstY*srcWidth + ndstX +1) ];
if((int)ndstY + 1 >= srcHeight)
color[0][1] = crDefault;
else
color[0][1] = pSrc[ (int)(((int)ndstY+1)*srcWidth + ndstX) ];
if((int)ndstY + 1 >= srcHeight || (int)ndstX + 1 >= srcWidth)
color[1][1] = crDefault;
else
color[1][1] = pSrc[ (int)(((int)ndstY+1)*srcWidth + ndstX+1) ];
alpha[0][0] = (color[0][0] & 0XFF000000) >> 24;
bColor[0][0] = (color[0][0] & 0XFF0000) >> 16;
gColor[0][0] = (color[0][0] & 0X00FF00) >> 8;
rColor[0][0] = color[0][0] & 0X0000FF;
alpha[1][0] = (color[1][0] & 0XFF000000) >> 24;
bColor[1][0] = (color[1][0] & 0XFF0000) >> 16;
gColor[1][0] = (color[1][0] & 0X00FF00) >> 8;
rColor[1][0] = color[1][0] & 0X0000FF;
alpha[0][1] = (color[0][1] & 0XFF000000) >> 24;
bColor[0][1] = (color[0][1] & 0XFF0000) >> 16;
gColor[0][1] = (color[0][1] & 0X00FF00) >> 8;
rColor[0][1] = color[0][1] & 0X0000FF;
alpha[1][1] = (color[1][1] & 0XFF000000) >> 24;
bColor[1][1] = (color[1][1] & 0XFF0000) >> 16;
gColor[1][1] = (color[1][1] & 0X00FF00) >> 8;
rColor[1][1] = color[1][1] & 0X0000FF;
//f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
ox = (ndstX - (int)ndstX);
oy = (ndstY - (int)ndstY);
rfinal = (1 - ox)*(1 - oy)*rColor[0][0] + ox*(1 - oy)*rColor[1][0] + (1-ox)*oy*rColor[0][1] + ox*oy*rColor[1][1];
gfinal = (1 - ox)*(1 - oy)*gColor[0][0] + ox*(1 - oy)*gColor[1][0] + (1-ox)*oy*gColor[0][1] + ox*oy*gColor[1][1];
bfinal = (1 - ox)*(1 - oy)*bColor[0][0] + ox*(1 - oy)*bColor[1][0] + (1-ox)*oy*bColor[0][1] + ox*oy*bColor[1][1];
afinal = (1 - ox)*(1 - oy)*alpha[0][0] + ox*(1 - oy)*alpha[1][0] + (1-ox)*oy*alpha[0][1] + ox*oy*alpha[1][1];
pDst[y * (int)dstWidth + x] = RGBA(rfinal,gfinal,bfinal,afinal);
}
else
{
pDst[y * (int)dstWidth + x] = crDefault;
}
}
}
}
需要对浮点型运算,改为整形预算。在模拟上测试过,旋转一张图片,整形预算要比浮点型预算快20倍。
改为整形运算代码。
view plaincopy to clipboardprint?
void RotateImageZhenxingBuf(const BYTE* src, int srcWidth, int srcHeight, BYTE*& dst, int& dstWidth, int& dstHeight, double angle)
{
double cosA = cos(angle);
double sinA = sin(angle);
double x1 = srcWidth * cosA;
double y1 = srcWidth * sinA;
double x2 = srcWidth * cosA - srcHeight * sinA;
double y2 = srcWidth * sinA + srcHeight * cosA;
double x3 = - srcHeight * sinA;
double y3 = srcHeight * cosA;
double minWidthD = min(0,min(x3,min(x1,x2)));
double minHeightD = min(0,min(y3,min(y1,y2)));
double maxWidthD = max(0,max(x3,max(x1,x2)));
double maxHeightD = max(0,max(y3,max(y1,y2)));
dstWidth = abs(minWidthD - maxWidthD) + 1;
dstHeight = abs(maxHeightD - minHeightD) + 1;
int minWidth= minWidthD;
int minHeight= minHeightD;
int maxWidth = maxWidthD;
int maxHeight = maxHeightD;
int ndstX = 0;
int ndstY = 0;
dst = new BYTE[dstWidth * dstHeight * 4];
UINT32 *pDst = (UINT32 *)dst;
UINT32 *pSrc = (UINT32 *)src;
UINT32 crDefault = ((UINT32 *)src)[0];
UINT32 color [2][2];
BYTE alpha[2][2];
BYTE rColor[2][2];
BYTE gColor[2][2];
BYTE bColor[2][2];
int afinal,rfinal,gfinal,bfinal;
long icosA = cosA * 256 * 256;
long isinA = sinA * 256 * 256;
int x;
int y;
int kx;
int ky;
for(int j=0; j < dstHeight; j++)
{
for(int i=0; i < dstWidth; i++)
{
ndstX = (i + minWidth) * icosA + (j + minHeight) * isinA;
ndstY = (j + minHeight) * icosA - (i +minWidth) * isinA;
ndstX = ndstX >> 8;
ndstY = ndstY >> 8;
if ( (ndstX >> 8) < srcWidth && (ndstX >> 8) >=0 && (ndstY >> 8) < srcHeight && (ndstY >> 8) >= 0)
{
kx = ndstX >> 8;
ky = ndstY >> 8;
x = ndstX & 0xFF;
y = ndstY & 0xFF;
color[0][0] = pSrc[ ky*srcWidth + kx ];
if(kx + 1 >= srcWidth)
color[1][0] = crDefault;
else
color[1][0] = pSrc[ ky*srcWidth + kx +1 ];
if(ky + 1 >= srcHeight)
color[0][1] = crDefault;
else
color[0][1] = pSrc[ (ky+1)*srcWidth + kx ];
if(ky + 1 >= srcHeight || kx + 1 >= srcWidth)
color[1][1] = crDefault;
else
color[1][1] = pSrc[ (ky+1)*srcWidth + kx+1 ];
alpha[0][0] = (color[0][0] & 0XFF000000) >> 24;
bColor[0][0] = (color[0][0] & 0XFF0000) >> 16;
gColor[0][0] = (color[0][0] & 0X00FF00) >> 8;
rColor[0][0] = color[0][0] & 0XFF;
alpha[1][0] = (color[1][0] & 0XFF000000) >> 24;
bColor[1][0] = (color[1][0] & 0XFF0000) >> 16;
gColor[1][0] = (color[1][0] & 0X00FF00) >> 8;
rColor[1][0] = color[1][0] & 0XFF;
alpha[0][1] = (color[0][1] & 0XFF000000) >> 24;
bColor[0][1] = (color[0][1] & 0XFF0000) >> 16;
gColor[0][1] = (color[0][1] & 0X00FF00) >> 8;
rColor[0][1] = color[0][1] & 0XFF;
alpha[1][1] = (color[1][1] & 0XFF000000) >> 24;
bColor[1][1] = (color[1][1] & 0XFF0000) >> 16;
gColor[1][1] = (color[1][1] & 0X00FF00) >> 8;
rColor[1][1] = color[1][1] & 0XFF;
afinal = (0x100 - x)*(0x100 - y)*alpha[0][0] + x*(0x100 - y)*alpha[1][0] + (0x100-x)*y*alpha[0][1] + x*y*alpha[1][1];
rfinal = (0x100 - x)*(0x100 - y)*rColor[0][0] + x*(0x100 - y)*rColor[1][0] + (0x100-x)*y*rColor[0][1] + x*y*rColor[1][1];
gfinal = (0x100 - x)*(0x100 - y)*gColor[0][0] + x*(0x100 - y)*gColor[1][0] + (0x100-x)*y*gColor[0][1] + x*y*gColor[1][1];
bfinal = (0x100 - x)*(0x100 - y)*bColor[0][0] + x*(0x100 - y)*bColor[1][0] + (0x100-x)*y*bColor[0][1] + x*y*bColor[1][1];
afinal = afinal >> 16;
if (afinal>255)
afinal = 255;
if (afinal<0)
afinal = 0;
rfinal = rfinal >> 16;
if (rfinal>255)
rfinal = 255;
if (rfinal<0)
rfinal = 0;
gfinal = gfinal >> 16;
if (gfinal>255)
gfinal = 255;
if (gfinal<0)
gfinal = 0;
bfinal = bfinal >> 16;
if (bfinal>255)
bfinal = 255;
if (bfinal<0)
bfinal = 0;
pDst[j * dstWidth + i] = RGBA(rfinal,gfinal,bfinal,afinal);
}
else
{
pDst[j * dstWidth + i] = crDefault;
}
}
}
}
void RotateImageZhenxingBuf(const BYTE* src, int srcWidth, int srcHeight, BYTE*& dst, int& dstWidth, int& dstHeight, double angle)
{
double cosA = cos(angle);
double sinA = sin(angle);
double x1 = srcWidth * cosA;
double y1 = srcWidth * sinA;
double x2 = srcWidth * cosA - srcHeight * sinA;
double y2 = srcWidth * sinA + srcHeight * cosA;
double x3 = - srcHeight * sinA;
double y3 = srcHeight * cosA;
double minWidthD = min(0,min(x3,min(x1,x2)));
double minHeightD = min(0,min(y3,min(y1,y2)));
double maxWidthD = max(0,max(x3,max(x1,x2)));
double maxHeightD = max(0,max(y3,max(y1,y2)));
dstWidth = abs(minWidthD - maxWidthD) + 1;
dstHeight = abs(maxHeightD - minHeightD) + 1;
int minWidth= minWidthD;
int minHeight= minHeightD;
int maxWidth = maxWidthD;
int maxHeight = maxHeightD;
int ndstX = 0;
int ndstY = 0;
dst = new BYTE[dstWidth * dstHeight * 4];
UINT32 *pDst = (UINT32 *)dst;
UINT32 *pSrc = (UINT32 *)src;
UINT32 crDefault = ((UINT32 *)src)[0];
UINT32 color [2][2];
BYTE alpha[2][2];
BYTE rColor[2][2];
BYTE gColor[2][2];
BYTE bColor[2][2];
int afinal,rfinal,gfinal,bfinal;
long icosA = cosA * 256 * 256;
long isinA = sinA * 256 * 256;
int x;
int y;
int kx;
int ky;
for(int j=0; j < dstHeight; j++)
{
for(int i=0; i < dstWidth; i++)
{
ndstX = (i + minWidth) * icosA + (j + minHeight) * isinA;
ndstY = (j + minHeight) * icosA - (i +minWidth) * isinA;
ndstX = ndstX >> 8;
ndstY = ndstY >> 8;
if ( (ndstX >> 8) < srcWidth && (ndstX >> 8) >=0 && (ndstY >> 8) < srcHeight && (ndstY >> 8) >= 0)
{
kx = ndstX >> 8;
ky = ndstY >> 8;
x = ndstX & 0xFF;
y = ndstY & 0xFF;
color[0][0] = pSrc[ ky*srcWidth + kx ];
if(kx + 1 >= srcWidth)
color[1][0] = crDefault;
else
color[1][0] = pSrc[ ky*srcWidth + kx +1 ];
if(ky + 1 >= srcHeight)
color[0][1] = crDefault;
else
color[0][1] = pSrc[ (ky+1)*srcWidth + kx ];
if(ky + 1 >= srcHeight || kx + 1 >= srcWidth)
color[1][1] = crDefault;
else
color[1][1] = pSrc[ (ky+1)*srcWidth + kx+1 ];
alpha[0][0] = (color[0][0] & 0XFF000000) >> 24;
bColor[0][0] = (color[0][0] & 0XFF0000) >> 16;
gColor[0][0] = (color[0][0] & 0X00FF00) >> 8;
rColor[0][0] = color[0][0] & 0XFF;
alpha[1][0] = (color[1][0] & 0XFF000000) >> 24;
bColor[1][0] = (color[1][0] & 0XFF0000) >> 16;
gColor[1][0] = (color[1][0] & 0X00FF00) >> 8;
rColor[1][0] = color[1][0] & 0XFF;
alpha[0][1] = (color[0][1] & 0XFF000000) >> 24;
bColor[0][1] = (color[0][1] & 0XFF0000) >> 16;
gColor[0][1] = (color[0][1] & 0X00FF00) >> 8;
rColor[0][1] = color[0][1] & 0XFF;
alpha[1][1] = (color[1][1] & 0XFF000000) >> 24;
bColor[1][1] = (color[1][1] & 0XFF0000) >> 16;
gColor[1][1] = (color[1][1] & 0X00FF00) >> 8;
rColor[1][1] = color[1][1] & 0XFF;
afinal = (0x100 - x)*(0x100 - y)*alpha[0][0] + x*(0x100 - y)*alpha[1][0] + (0x100-x)*y*alpha[0][1] + x*y*alpha[1][1];
rfinal = (0x100 - x)*(0x100 - y)*rColor[0][0] + x*(0x100 - y)*rColor[1][0] + (0x100-x)*y*rColor[0][1] + x*y*rColor[1][1];
gfinal = (0x100 - x)*(0x100 - y)*gColor[0][0] + x*(0x100 - y)*gColor[1][0] + (0x100-x)*y*gColor[0][1] + x*y*gColor[1][1];
bfinal = (0x100 - x)*(0x100 - y)*bColor[0][0] + x*(0x100 - y)*bColor[1][0] + (0x100-x)*y*bColor[0][1] + x*y*bColor[1][1];
afinal = afinal >> 16;
if (afinal>255)
afinal = 255;
if (afinal<0)
afinal = 0;
rfinal = rfinal >> 16;
if (rfinal>255)
rfinal = 255;
if (rfinal<0)
rfinal = 0;
gfinal = gfinal >> 16;
if (gfinal>255)
gfinal = 255;
if (gfinal<0)
gfinal = 0;
bfinal = bfinal >> 16;
if (bfinal>255)
bfinal = 255;
if (bfinal<0)
bfinal = 0;
pDst[j * dstWidth + i] = RGBA(rfinal,gfinal,bfinal,afinal);
}
else
{
pDst[j * dstWidth + i] = crDefault;
}
}
}
}
用Imaging接口加载png图片,并调用RotateImageBuf进行旋转,最后返回IImage接口。
view plaincopy to clipboardprint?
// need to delete pImagebuf;
HRESULT RotateImage(IImagingFactory *pImgFactory, IImage *pImage, IImage * &pImageOut, LPBYTE &pImageBuf, double angle)
{
HRESULT hr = S_OK;
IBitmapImage *pIBitmap = NULL;
ImageInfo ImInfo;
pImage->GetImageInfo(&ImInfo);
if((ImInfo.PixelFormat & 0xFF00)>>8 != 32)
{
hr = S_FALSE;
goto Error;
}
if(S_OK != pImgFactory->CreateBitmapFromImage(
pImage, ImInfo.Width, ImInfo.Height, ImInfo.PixelFormat, InterpolationHintDefault, &pIBitmap))
{
hr = S_FALSE;
goto Error;
}
RECT rcLocked ={0,0,ImInfo.Width,ImInfo.Height};
BitmapData bmpData;
if(S_OK != pIBitmap->LockBits(&rcLocked, ImageLockModeRead | ImageLockModeWrite, ImInfo.PixelFormat, &bmpData))
{
hr = S_FALSE;
goto Error;
}
BYTE *pDst = NULL;
int nDstWidth=0,nDstHeight=0;
RotateImageZhenxingBuf((BYTE *)bmpData.Scan0, ImInfo.Width, ImInfo.Height, pDst, nDstWidth, nDstHeight, angle);
pIBitmap->UnlockBits(&bmpData);
BitmapData bmpDataNew;
bmpDataNew.Height = nDstHeight;
bmpDataNew.Width = nDstWidth;
bmpDataNew.PixelFormat = ImInfo.PixelFormat;
bmpDataNew.Stride = nDstWidth * 4;
bmpDataNew.Reserved = 0;
bmpDataNew.Scan0 = (void *)pDst;
IBitmapImage *pBmpImageNew = NULL;
hr = pImgFactory->CreateBitmapFromBuffer(&bmpDataNew, &pBmpImageNew);
IImage * pImageNew = NULL;
pBmpImageNew->QueryInterface(IID_IImage, (void **)&pImageNew);
pImageOut = pImageNew;
pImageBuf = pDst;
Error:
if(pBmpImageNew)
pBmpImageNew->Release();
if(pIBitmap)
pIBitmap->Release();
return hr;
}
// need to delete pImagebuf;
HRESULT RotateImage(IImagingFactory *pImgFactory, IImage *pImage, IImage * &pImageOut, LPBYTE &pImageBuf, double angle)
{
HRESULT hr = S_OK;
IBitmapImage *pIBitmap = NULL;
ImageInfo ImInfo;
pImage->GetImageInfo(&ImInfo);
if((ImInfo.PixelFormat & 0xFF00)>>8 != 32)
{
hr = S_FALSE;
goto Error;
}
if(S_OK != pImgFactory->CreateBitmapFromImage(
pImage, ImInfo.Width, ImInfo.Height, ImInfo.PixelFormat, InterpolationHintDefault, &pIBitmap))
{
hr = S_FALSE;
goto Error;
}
RECT rcLocked ={0,0,ImInfo.Width,ImInfo.Height};
BitmapData bmpData;
if(S_OK != pIBitmap->LockBits(&rcLocked, ImageLockModeRead | ImageLockModeWrite, ImInfo.PixelFormat, &bmpData))
{
hr = S_FALSE;
goto Error;
}
BYTE *pDst = NULL;
int nDstWidth=0,nDstHeight=0;
RotateImageZhenxingBuf((BYTE *)bmpData.Scan0, ImInfo.Width, ImInfo.Height, pDst, nDstWidth, nDstHeight, angle);
pIBitmap->UnlockBits(&bmpData);
BitmapData bmpDataNew;
bmpDataNew.Height = nDstHeight;
bmpDataNew.Width = nDstWidth;
bmpDataNew.PixelFormat = ImInfo.PixelFormat;
bmpDataNew.Stride = nDstWidth * 4;
bmpDataNew.Reserved = 0;
bmpDataNew.Scan0 = (void *)pDst;
IBitmapImage *pBmpImageNew = NULL;
hr = pImgFactory->CreateBitmapFromBuffer(&bmpDataNew, &pBmpImageNew);
IImage * pImageNew = NULL;
pBmpImageNew->QueryInterface(IID_IImage, (void **)&pImageNew);
pImageOut = pImageNew;
pImageBuf = pDst;
Error:
if(pBmpImageNew)
pBmpImageNew->Release();
if(pIBitmap)
pIBitmap->Release();
return hr;
}
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jinhaijian/archive/2010/05/25/5623654.aspx