【发布时间】:2019-03-13 10:49:48
【问题描述】:
我正在尝试在我的 MFC 应用程序中实现抗锯齿,我正在使用this tutorial 中描述的技术。
- 创建一个与原始位图大小相同的位图(2x、4x、8x)。
- 在调整大小的位图上绘制(我只使用简单的图形(线、圆等)。
- 将 StretchBlt 模式设置为半色调。
- 并使用 StretchBlt 将大小调整为原始大小。
使用这种方式,在调整大小的位图中绘制它可以工作,但我想创建一个更通用的函数来接收已经绘制的位图并返回抗锯齿,我尝试了这个:
static HBITMAP AntiAliasing(HBITMAP hBitmap)
{
int escala = 4;
HBITMAP bmp = __copia(hBitmap); // Copy the bitmap.
HDC hMemDC = CreateCompatibleDC(NULL);
HBITMAP bmpAntigo1 = (HBITMAP)::SelectObject(hMemDC, bmp);
BITMAP bitmap;
::GetObject(hBitmap, sizeof(BITMAP), &bitmap);
// Create a bitmap (2x, 4x, 8x) the size of the original bitmap.
HDC hDCDimensionado = ::CreateCompatibleDC(hMemDC);
HBITMAP bmpDimensionado = ::CreateCompatibleBitmap(hDCDimensionado,
bitmap.bmWidth * escala,
bitmap.bmHeight * escala);
HBITMAP hBmpVelho = (HBITMAP)::SelectObject(hDCDimensionado, bmpDimensionado);
// I also tried with {BLACKONWHITE, HALFTONE, WHITEONBLACK}
int oldStretchBltMode2 = ::SetStretchBltMode(hDCDimensionado, COLORONCOLOR);
// Resize the bitmap to the new size.
::StretchBlt(hDCDimensionado,
0, 0, bitmap.bmWidth * escala, bitmap.bmHeight * escala,
hMemDC,
0, 0, bitmap.bmWidth, bitmap.bmHeight,
SRCCOPY);
/*
* Here the bitmap has lost his colors and became black and white.
*/
::SetStretchBltMode(hDCDimensionado, oldStretchBltMode2);
// Set StretchBltMode to halfTone so can mimic the anti aliasing effect.
int oldStretchBltMode = ::SetStretchBltMode(hMemDC, HALFTONE);
// resize to the original size.
::StretchBlt(hMemDC,
0, 0, bitmap.bmWidth, bitmap.bmHeight,
hDCDimensionado,
0, 0, escala * bitmap.bmWidth, escala * bitmap.bmHeight,
SRCCOPY);
::SetStretchBltMode(hMemDC, oldStretchBltMode);
::SelectObject(hMemDC, bmpAntigo1);
::DeleteDC(hMemDC);
::SelectObject(hDCDimensionado, hBmpVelho);
DeleteDC(hDCDimensionado);
return bmp;
}
但是这个功能不起作用,结果失去了颜色(所有图纸都变黑了)并且没有抗锯齿。
任何帮助将不胜感激!
【问题讨论】:
-
即使这段代码可以工作,你能得到的“最佳”结果将是原始位图的模糊版本,它丢失了所有细节。你会失望的。谷歌"FXAA" 寻找更好的算法。
-
本文中介绍的技术通过光栅化图像并以较低的分辨率显示它来工作。您的尝试不会奏效,因为源图像已在显示分辨率下进行了光栅化。膨胀它不会恢复额外的像素信息。它只会放大光栅化错误。