各位热心人,帮帮忙哦!

light_sun 2004-11-25 07:00:36
我想用LoadImage函数读入一个位图,并用StretchBlt函数缩小显示到某个窗口,但是发现如果该函数按原来尺寸显示出来没问题,但如果让它缩小显示就不对,感觉图象色彩严重失真,请高手不吝指教。

我是调用SDK的这个函数,不是CDC类的,而且SetStretchBltMode(COLORONCOLOR)设置模式,但还是不对。如果知道其它方法可以不失真显示伸缩位图,请相告。虽然分不多,但哪位高手能帮忙搞定,分数一定送出。
...全文
81 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
light_sun 2004-11-25
  • 打赏
  • 举报
回复
谢谢帮忙!我试试上面的程序,可以的话就散分!
柯本 2004-11-25
  • 打赏
  • 举报
回复
StretchBlt用SRCCOPY
SetStretchBltMode用COLORONCOLOR
应该可以
I_Love_CPP 2004-11-25
  • 打赏
  • 举报
回复
上面的是放大的程序,你仿照就可以自己写缩小的了。
I_Love_CPP 2004-11-25
  • 打赏
  • 举报
回复
#define WIDTHBYTES(bits) (((bits) + 31) / 32 * 4) // for padding

///////////////////////////////////////////////////////////////////
// Function name : ZoomOutBmp
// Description : creates a new bitmap which is a grayscale
// zoomed out version of the original
// Return type : HDIB - handle to a new bitmap
// Argument : double zoom - number of times to zoom out
// Argument : HDIB hSrcDIB - handle to a source bitmap
///////////////////////////////////////////////////////////////////
HDIB ZoomOutBmp(double zoom, HDIB hSrcDIB)
{
if (hSrcDIB == NULL) // nothing to do
return NULL;

if (zoom < 1) // no zoomin in this function
return NULL;

LPSTR pSrcDIB = (LPSTR) ::GlobalLock((HGLOBAL) hSrcDIB);

BITMAPINFOHEADER& bmihSrc = *(BITMAPINFOHEADER*)pSrcDIB;
ASSERT(bmihSrc.biBitCount == 1); // only monochrome bitmaps supported
LPSTR pSrcBits = (LPSTR) (pSrcDIB + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*2);

BITMAPINFOHEADER bmihDst = bmihSrc;
bmihDst.biWidth = (LONG)(bmihDst.biWidth / zoom + 0.5);
bmihDst.biHeight = (LONG)(bmihDst.biHeight / zoom + 0.5);
bmihDst.biBitCount = 8; // grayscale in any case
bmihDst.biClrUsed = 0;

// prepare destination bitmap
DWORD dwDIBSize = sizeof(bmihDst) + sizeof(RGBQUAD)*256 +
WIDTHBYTES(bmihDst.biWidth * bmihDst.biBitCount) * bmihDst.biHeight;

bmihDst.biSizeImage = dwDIBSize;

// allocate space for the new bitmap
HDIB hDstDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwDIBSize);

if (hDstDIB == 0) {
::GlobalUnlock((HGLOBAL) hSrcDIB);
return NULL;
}

LPSTR pDstDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDstDIB);

// copy header
memcpy(pDstDIB, &bmihDst, sizeof(bmihDst));

// prepare grayscale palette
for (int i=0; i < (1 << bmihDst.biBitCount); i++) {

RGBQUAD& palEntry = *(RGBQUAD*)(pDstDIB + sizeof(bmihDst) + i * sizeof(RGBQUAD));
palEntry.rgbRed = palEntry.rgbGreen = palEntry.rgbBlue = i;

}

LPSTR pDstBits = (LPSTR) (pDstDIB + sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD)*256);

// now fill the bits
LPSTR curSrcLineBits, curDstLineBits;
int j, k;
int scale = (int)(zoom + 0.5); // integer zoom out factor, i.e. 1:5
int hBase, vBase;
unsigned char value;

// for every _scale_ lines in a source bitmap we will get one line
// in the destination bitmap. Similarly for _scale_ columns in the
// source we'll obtain one destination column.

for (int strip=0; strip < bmihDst.biHeight; strip++) { // for every dst line

curDstLineBits = pDstBits + strip * WIDTHBYTES(bmihDst.biWidth * bmihDst.biBitCount);
vBase = int(strip * zoom + 0.5);

for (i=0; i < scale; i++) { // accumulate _scale_ rows

curSrcLineBits = pSrcBits + (vBase + i) * WIDTHBYTES(bmihSrc.biWidth * bmihSrc.biBitCount);

// prepare horizontally condensed lines for this strip
for (j=0; j < bmihDst.biWidth; j++) { // for all bits in line

hBase = int(j * zoom + 0.5); // mapped index on source
for (k=0; k < scale; k++) { // accumulate _scale_ columns

value = (curSrcLineBits[(hBase+k)/8] & (1 << (7 - (hBase+k)%8))) ? 0xff : 0;
curDstLineBits[j] += value / scale / scale; // main accumulator
}
}
}

}

// unlock memory
::GlobalUnlock((HGLOBAL) hSrcDIB);
::GlobalUnlock((HGLOBAL) hDstDIB);

return hDstDIB;
}

This function may be improved in several ways, for example, working with a weighted fraction of a pixel or centering the accumulated source pixels. However, the resulting visual impovement is not significant.

19,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧