RGB565图片旋转后颜色显示不对的有关问题
求助RGB565图片旋转后颜色显示不对的问题?
程序运行后,能显示旋转后的图片,透明通道正常,只是图片颜色总是不对。
请各位高手帮忙看下问题在哪里!!!
原图片已经读入存储空间,下面函数是新建一存储空间,把旋转后的图片像素信息存入,
显示程序按原图同样方式读出显示。
typedef struct dibData
{
DWORD type; //MAGIC
DWORD width;
DWORD height;
DWORD bitcount; //16
DWORD widthBytes; //对齐
DWORD widthAlphas; //width
DWORD reserved0;
DWORD reserved1;
DWORD reserved2;
DWORD reserved3;
BYTE* alpha;
BYTE dib[1];
}DIBDATA_Z,*LPDIBDATA_Z;
///RGB565
#define RGB565_MASK_RED 0xF800
#define RGB565_MASK_GREEN 0x3F
#define RGB565_MASK_BLUE 0x001F
#define DIB_BITCOUNT 16
#define B_565(c) (((c)&0xF800)>>11)
#define G_565(c) (((c)&0x07E0)>>5)
#define R_565(c) ((c)&0x001F)
#define RGB_565(r,g,b) (WORD)((((b)>>3)<<11)|(((g)>>2)<<5)|((r)>>3))
///////////////////////////////////////////////////////////////
BOOL CLiImage::RotateImageBuffer(
const BYTE* pSrcBuf, // 原图像缓冲区(RGB565)
DWORD dwSrcWidth, // 原图像像素宽度
DWORD dwSrcHeight, // 原图像像素高度
int iRotateAngle, // 旋转角度(单位:度)
CLiImage* pNewImage // 新图对像类
)
{
// 参数有效性
if (pSrcBuf==NULL || dwSrcWidth==0 || dwSrcHeight==0)
{
RETAILMSG(1,(L"[RotateImageBuffer]:====pSrcBuf==NULL======\n"));
return FALSE;
}
// 计算有效的旋转角
int dbAngle = iRotateAngle%360;
// 旋转角度为0或为360不需要旋转
if (dbAngle==0 || dbAngle==360)
{
RETAILMSG(1,(L"[RotateImageBuffer]:====dbAngle==0/==360======\n"));
return FALSE;
}
PWFBYTE pDstBuf = NULL; //输出旋转后图像缓冲区指针(RGB565)
DWORD dwDstWidth = 0; // 输出旋转后图像像素宽度
DWORD dwDstHeight = 0; // 输出旋转后图像像素高度
//定义原图片宽高
int m_iWidth = dwSrcWidth;
int m_iHeight = dwSrcHeight;
//计算角度对应的弧度值
// 计算sin(dbAngle)和cos(dbAngle)的值
//double dbPI = 3.1415926535; //dbPI/180=0.0174532925
double dbA = dbAngle*-0.0174532925;
double sinA = sin(dbA);
double cosA = cos(dbA);
int dstWidth = 0, dstHeight = 0;
int num1 = 0, num2 = 0;
UINT crDefault = 0;
// 以位图中点为原点,建立数学坐标系(因为这里我们只要得到新图的宽高,所以不用转到屏幕坐标系)
// 约定第一象限点(w/2,h/2)为第1点,依次第二象限第2点,三象限第3点,四象限第4点
// 容易知道:dstWidth = max(一对主副对角线上两点横坐标距离), dstHeight类似
// 在数学坐标系中,某点(x0,y0)顺时针旋转A度后的坐标公式为:(x1, y1)=(x0*cosA+y0*sinA, -x0*sinA+y0*cosA)
//以图片中心点为原点,坐标值/2
double w_2 = 0.5*m_iWidth;
double h_2 = 0.5*m_iHeight;
double cosAW_2 = cosA*w_2;
double sinAW_2 = sinA*w_2;
double cosAH_2 = cosA*h_2;
double sinAH_2 = sinA*h_2;
/////旋转后图片的4个点的坐标值(x1,y1),(x2,y2),(x3,y3),(x4,y4)
double DstX1 = cosAW_2 + sinAH_2;
double DstY1 = cosAH_2 - sinAW_2;
double DstX2 = cosAW_2 - sinAH_2;
double DstY2 = -sinAW_2 - cosAH_2;
double DstX3 = -cosAW_2 - sinAH_2;
double DstY3 = sinAW_2 - cosAH_2;
double DstX4 = sinAH_2 - cosAW_2;
double DstY4 = sinAW_2 + cosAH_2;
// 计算旋转后图像的宽度和高度
dstWidth = (int)(max(fabs(DstX4-DstX2),fabs(DstX3-DstX1)) + 0.5);
dstHeight = (int)(max(fabs(DstY4-DstY2),fabs(DstY3-DstY1)) + 0.5);
DWORD m_iWidth4 = m_iWidth*2;
m_iWidth4 = m_iWidth4 + (4 - m_iWidth%4);
DWORD dstWidth4 = dstWidth*2;
dstWidth4 = dstWidth4 + (4 - dstWidth4%4);
DWORD m_iWidth4 = (((m_iWidth*16 + 31)/32)*32)/8/*((m_iWidth*16+ 31) & ~31) >> 3*/; //原图每行位值
DWORD dstWidth4 = (((dstWidth*16 + 31)/32)*32)/8;/*((dstWidth*16+ 31) & ~31) >> 3*/; //转后图每行位值
////计算旋转后图像的总存储空间
DWORD iDibSize = offsetof_(DIBDATA_Z, dib) ; //LPDIBDATA_Z_SIZE结构体存储占用位
DWORD dwDstBufSize = iDibSize+dstWidth4*dstHeight;
if( m_pDib->alpha )
{
程序运行后,能显示旋转后的图片,透明通道正常,只是图片颜色总是不对。
请各位高手帮忙看下问题在哪里!!!
原图片已经读入存储空间,下面函数是新建一存储空间,把旋转后的图片像素信息存入,
显示程序按原图同样方式读出显示。
typedef struct dibData
{
DWORD type; //MAGIC
DWORD width;
DWORD height;
DWORD bitcount; //16
DWORD widthBytes; //对齐
DWORD widthAlphas; //width
DWORD reserved0;
DWORD reserved1;
DWORD reserved2;
DWORD reserved3;
BYTE* alpha;
BYTE dib[1];
}DIBDATA_Z,*LPDIBDATA_Z;
///RGB565
#define RGB565_MASK_RED 0xF800
#define RGB565_MASK_GREEN 0x3F
#define RGB565_MASK_BLUE 0x001F
#define DIB_BITCOUNT 16
#define B_565(c) (((c)&0xF800)>>11)
#define G_565(c) (((c)&0x07E0)>>5)
#define R_565(c) ((c)&0x001F)
#define RGB_565(r,g,b) (WORD)((((b)>>3)<<11)|(((g)>>2)<<5)|((r)>>3))
///////////////////////////////////////////////////////////////
BOOL CLiImage::RotateImageBuffer(
const BYTE* pSrcBuf, // 原图像缓冲区(RGB565)
DWORD dwSrcWidth, // 原图像像素宽度
DWORD dwSrcHeight, // 原图像像素高度
int iRotateAngle, // 旋转角度(单位:度)
CLiImage* pNewImage // 新图对像类
)
{
// 参数有效性
if (pSrcBuf==NULL || dwSrcWidth==0 || dwSrcHeight==0)
{
RETAILMSG(1,(L"[RotateImageBuffer]:====pSrcBuf==NULL======\n"));
return FALSE;
}
// 计算有效的旋转角
int dbAngle = iRotateAngle%360;
// 旋转角度为0或为360不需要旋转
if (dbAngle==0 || dbAngle==360)
{
RETAILMSG(1,(L"[RotateImageBuffer]:====dbAngle==0/==360======\n"));
return FALSE;
}
PWFBYTE pDstBuf = NULL; //输出旋转后图像缓冲区指针(RGB565)
DWORD dwDstWidth = 0; // 输出旋转后图像像素宽度
DWORD dwDstHeight = 0; // 输出旋转后图像像素高度
//定义原图片宽高
int m_iWidth = dwSrcWidth;
int m_iHeight = dwSrcHeight;
//计算角度对应的弧度值
// 计算sin(dbAngle)和cos(dbAngle)的值
//double dbPI = 3.1415926535; //dbPI/180=0.0174532925
double dbA = dbAngle*-0.0174532925;
double sinA = sin(dbA);
double cosA = cos(dbA);
int dstWidth = 0, dstHeight = 0;
int num1 = 0, num2 = 0;
UINT crDefault = 0;
// 以位图中点为原点,建立数学坐标系(因为这里我们只要得到新图的宽高,所以不用转到屏幕坐标系)
// 约定第一象限点(w/2,h/2)为第1点,依次第二象限第2点,三象限第3点,四象限第4点
// 容易知道:dstWidth = max(一对主副对角线上两点横坐标距离), dstHeight类似
// 在数学坐标系中,某点(x0,y0)顺时针旋转A度后的坐标公式为:(x1, y1)=(x0*cosA+y0*sinA, -x0*sinA+y0*cosA)
//以图片中心点为原点,坐标值/2
double w_2 = 0.5*m_iWidth;
double h_2 = 0.5*m_iHeight;
double cosAW_2 = cosA*w_2;
double sinAW_2 = sinA*w_2;
double cosAH_2 = cosA*h_2;
double sinAH_2 = sinA*h_2;
/////旋转后图片的4个点的坐标值(x1,y1),(x2,y2),(x3,y3),(x4,y4)
double DstX1 = cosAW_2 + sinAH_2;
double DstY1 = cosAH_2 - sinAW_2;
double DstX2 = cosAW_2 - sinAH_2;
double DstY2 = -sinAW_2 - cosAH_2;
double DstX3 = -cosAW_2 - sinAH_2;
double DstY3 = sinAW_2 - cosAH_2;
double DstX4 = sinAH_2 - cosAW_2;
double DstY4 = sinAW_2 + cosAH_2;
// 计算旋转后图像的宽度和高度
dstWidth = (int)(max(fabs(DstX4-DstX2),fabs(DstX3-DstX1)) + 0.5);
dstHeight = (int)(max(fabs(DstY4-DstY2),fabs(DstY3-DstY1)) + 0.5);
DWORD m_iWidth4 = m_iWidth*2;
m_iWidth4 = m_iWidth4 + (4 - m_iWidth%4);
DWORD dstWidth4 = dstWidth*2;
dstWidth4 = dstWidth4 + (4 - dstWidth4%4);
DWORD m_iWidth4 = (((m_iWidth*16 + 31)/32)*32)/8/*((m_iWidth*16+ 31) & ~31) >> 3*/; //原图每行位值
DWORD dstWidth4 = (((dstWidth*16 + 31)/32)*32)/8;/*((dstWidth*16+ 31) & ~31) >> 3*/; //转后图每行位值
////计算旋转后图像的总存储空间
DWORD iDibSize = offsetof_(DIBDATA_Z, dib) ; //LPDIBDATA_Z_SIZE结构体存储占用位
DWORD dwDstBufSize = iDibSize+dstWidth4*dstHeight;
if( m_pDib->alpha )
{