cooska

前人种树,后人乘凉

导航

Windows Mobile上实现图片任意角度旋转

Posted on 2011-01-29 17:10  cooska  阅读(410)  评论(0编辑  收藏  举报

Windows Mobile上实现图片任意角度旋转

作者:金海建

目的:在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