简单代码如下:// 获取DIB调色板,并选中它
if (pPal != NULL)
{
hPal = (HPALETTE) pPal->m_hObject; // 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
} // 设置显示模式
::SetStretchBltMode(hDC, COLORONCOLOR); // 非原始大小,拉伸。
bSuccess = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
if (pPal != NULL)
{
hPal = (HPALETTE) pPal->m_hObject; // 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
} // 设置显示模式
::SetStretchBltMode(hDC, COLORONCOLOR); // 非原始大小,拉伸。
bSuccess = ::StretchDIBits(hDC, // hDC
lpDCRect->left, // DestX
lpDCRect->top, // DestY
RECTWIDTH(lpDCRect), // nDestWidth
RECTHEIGHT(lpDCRect), // nDestHeight
lpDIBRect->left, // SrcX
lpDIBRect->top, // SrcY
RECTWIDTH(lpDIBRect), // wSrcWidth
RECTHEIGHT(lpDIBRect), // wSrcHeight
lpDIBBits, // lpBits
(LPBITMAPINFO)lpDIBHdr, // lpBitsInfo
DIB_RGB_COLORS, // wUsage
SRCCOPY); // dwROP
}
{
hPal = (HPALETTE) pPal->m_hObject; // 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
}
int palsize;
//由于StretchBits图像坐标从左下角开始,故要转换图像坐标
// if (nSrcHeight != nDestHeight){
int iTop = YSrc, iBottom = YSrc+nSrcHeight-1, iHeight = GetHeight()-1;
YSrc = iHeight - iBottom;
// } palsize=PALETTESIZE(m_nBitCount);//if m_nBitCount==24 then palsize=0
//if it is 8, palsize=256 if is 4,then 16
pbmi=(BITMAPINFO *)new BYTE[sizeof(BITMAPINFO)+sizeof(RGBQUAD)*palsize];
memcpy(pbmi->bmiColors,m_lpPalette,sizeof(RGBQUAD)*palsize); HPALETTE hOldPal=NULL; // 以前的调色板
HPALETTE hPal=NULL; // DIB调色板
// 获取DIB调色板,并选中它
if (m_pPal != NULL)
{
hPal = (HPALETTE) m_pPal->m_hObject; // 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, true);
//::RealizePalette(hDC);
}
pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth=m_nWidth;
pbmi->bmiHeader.biHeight=m_nHeight;
pbmi->bmiHeader.biPlanes=1;
pbmi->bmiHeader.biBitCount=m_nBitCount;
pbmi->bmiHeader.biCompression=BI_RGB;
pbmi->bmiHeader.biSizeImage=0;
pbmi->bmiHeader.biXPelsPerMeter=0;
pbmi->bmiHeader.biYPelsPerMeter=0;
pbmi->bmiHeader.biClrUsed=0;
pbmi->bmiHeader.biClrImportant=0; SetStretchBltMode(hDC, HALFTONE);//HALFTONE
int ret=StretchDIBits(hDC,XDest,YDest,nDestWidth,nDestHeight,
XSrc,YSrc,nSrcWidth,nSrcHeight,m_lpBits,
pbmi,iUsage,dwRop);
// 恢复以前的调色板
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, true);
//::RealizePalette(hDC);
}
delete[] pbmi;
return ret;
2:Colors table超过236色的话,不可能不失真,因为windows保留了20色作为内部系统调色板,此20色不会被改变..
其实你可以试试用window里的画图在256色设置下打开你的8Bit位图来看看它的显示..
而且我在32位真彩下显示图像一切正常。
你有email么?
我给你发个图像你打开看看?
我找到一个例子可以打开图像,并且不失真,但是我感觉他的代码和我的基本一样,郁闷中
SelectPalette()只是选入,并没实现,必须RealizePalette()才实现..发你那张图来看看:
[email protected]
int XDest,int YDest,int nDestWidth,int nDestHeight,
int XSrc,int YSrc,int nSrcWidth,int nSrcHeight,
UINT iUsage,DWORD dwRop)
{
BITMAPINFO *pbmi;
int palsize;
HPALETTE hOldPal=NULL; // 以前的调色板
HPALETTE hPal=NULL; // DIB调色板
//由于StretchBits图像坐标从左下角开始,故要转换图像坐标
// if (nSrcHeight != nDestHeight){
int iTop = YSrc, iBottom = YSrc+nSrcHeight-1, iHeight = GetHeight()-1;
YSrc = iHeight - iBottom;
// }
// 获取DIB调色板,并选中它
if (m_pPal != NULL)
{
hPal = (HPALETTE) m_pPal->m_hObject;
// 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, false);
int nCour = ::RealizePalette(hDC);
}
// 恢复以前的调色板
if (hOldPal != NULL)
{
::SelectPalette(hDC, hOldPal, true);
}
palsize=PALETTESIZE(m_nBitCount);//if m_nBitCount==24 then palsize=0
//if it is 8, palsize=256 if is 4,then 16
pbmi=(BITMAPINFO *)new BYTE[sizeof(BITMAPINFO)+sizeof(RGBQUAD)*palsize];
memcpy(pbmi->bmiColors,m_lpPalette,sizeof(RGBQUAD)*palsize);
pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth=m_nWidth;
pbmi->bmiHeader.biHeight=m_nHeight;
pbmi->bmiHeader.biPlanes=1;
pbmi->bmiHeader.biBitCount=m_nBitCount;
pbmi->bmiHeader.biCompression=BI_RGB;
pbmi->bmiHeader.biSizeImage=0;
pbmi->bmiHeader.biXPelsPerMeter=0;
pbmi->bmiHeader.biYPelsPerMeter=0;
pbmi->bmiHeader.biClrUsed=0;
pbmi->bmiHeader.biClrImportant=0; SetStretchBltMode(hDC, COLORONCOLOR);//HALFTONE
int ret=::StretchDIBits(hDC,XDest,YDest,nDestWidth,nDestHeight,
XSrc,YSrc,nSrcWidth,nSrcHeight,m_lpBits,
pbmi,iUsage,dwRop);
delete[] pbmi;
return ret;
}
分不够我可以在给你加,只要能解决问题就行
int XSrc,int YSrc,int nSrcWidth,int nSrcHeight,
UINT iUsage,DWORD dwRop)
{
BITMAPINFO *pbmi;
int palsize;
HPALETTE hOldPal=NULL; // 以前的调色板
HPALETTE hPal=NULL; // DIB调色板
//由于StretchBits图像坐标从左下角开始,故要转换图像坐标
//if (nSrcHeight != nDestHeight){
int iTop = YSrc, iBottom = YSrc+nSrcHeight-1, iHeight = GetHeight()-1;
YSrc = iHeight - iBottom;
// }
// 获取DIB调色板,并选中它
if (m_pPal != NULL)
{
hPal = (HPALETTE) m_pPal->m_hObject;
// 选中调色板
hOldPal = ::SelectPalette(hDC, hPal, false);
int nCour = ::RealizePalette(hDC);
}
// 恢复以前的调色板
/*if (hOldPal != NULL)//放在后面
{
::SelectPalette(hDC, hOldPal, true);
}*/
palsize=PALETTESIZE(m_nBitCount);//if m_nBitCount==24 then palsize=0
//if it is 8, palsize=256 if is 4,then 16
pbmi=(BITMAPINFO *)new BYTE[sizeof(BITMAPINFO)+sizeof(RGBQUAD)*palsize];
memcpy(pbmi->bmiColors,m_lpPalette,sizeof(RGBQUAD)*palsize);
pbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
pbmi->bmiHeader.biWidth=m_nWidth;
pbmi->bmiHeader.biHeight=m_nHeight;
pbmi->bmiHeader.biPlanes=1;
pbmi->bmiHeader.biBitCount=m_nBitCount;
pbmi->bmiHeader.biCompression=BI_RGB;
pbmi->bmiHeader.biSizeImage=0;
pbmi->bmiHeader.biXPelsPerMeter=0;
pbmi->bmiHeader.biYPelsPerMeter=0;
pbmi->bmiHeader.biClrUsed=0;
pbmi->bmiHeader.biClrImportant=0; SetStretchBltMode(hDC, COLORONCOLOR);//HALFTONE
int ret=::StretchDIBits(hDC,XDest,YDest,nDestWidth,nDestHeight,
XSrc,YSrc,nSrcWidth,nSrcHeight,m_lpBits,
pbmi,iUsage,dwRop); if (hOldPal != NULL)//放在后面
{
::SelectPalette(hDC, hOldPal, FALSE);
}
delete[] pbmi;
return ret;
}==================================================================
试试看..
多文档的话,呵呵。。实际上只能有一个前景调色板.
因为偶写的不会失真,虽然偶是用CreateDIBSection(),但同样用StretchDIBits()来test(本来偶是用MemDC来显示的)..