I'm trying to implement anti-aliasing in my MFC app, I'm using the technique described in this tutorial.
Using this way, drawing in the resized bitmap it works, but I want to create a more generic function that receives a bitmap with the drawing already made and return with the anti-aliasing, I tried this:
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;
}
But this function doesn't work, the result loses its colors (all drawings became black) and there isn't anti aliasing.
Any help will be appreciated!
From documentation for CreateCompatibleBitmap
:
Note: When a memory device context is created, it initially has a 1-by-1 monochrome bitmap selected into it. If this memory device context is used in CreateCompatibleBitmap, the bitmap that is created is a monochrome bitmap. To create a color bitmap, use the HDC that was used to create the memory device context, as shown in the following code:
Change the code and supply hdc
for the desktop as show below:
HDC hdc = ::GetDC(0);
HBITMAP bmpDimensionado = ::CreateCompatibleBitmap(hdc, ...)
::ReleaseDC(0, hdc);
Use other methods such Direct2D with Gaussian blur effect, or use GDI+ instead with interpolation mode:
Gdiplus::GdiplusStartup...
void foo(HDC hdc)
{
Gdiplus::Bitmap bitmap(L"file.bmp");
if(bitmap.GetLastStatus() != 0)
return 0;
auto w = bitmap.GetWidth();
auto h = bitmap.GetHeight();
auto maxw = w * 2;
auto maxh = h * 2;
Gdiplus::Bitmap membmp(maxw, maxh);
Gdiplus::Graphics memgr(&membmp);
memgr.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBilinear);
memgr.DrawImage(&bitmap, 0, 0, maxw, maxh);
Gdiplus::Graphics gr(hdc);
gr.SetInterpolationMode(Gdiplus::InterpolationModeHighQualityBilinear);
gr.DrawImage(&membmp, 0, 0, w, h);
}
#define GDIPVER 0x0110 //add this to precompiled header file
void blur(HDC hdc)
{
Gdiplus::Graphics graphics(hdc);
Gdiplus::Bitmap bitmap(L"file.bmp");
if(bitmap.GetLastStatus() != 0)
return;
Gdiplus::Blur blur;
Gdiplus::BlurParams blur_param;
blur_param.radius = 3; //change the radius for different result
blur_param.expandEdge = TRUE;
blur.SetParameters(&blur_param);
bitmap.ApplyEffect(&blur, NULL);
graphics.DrawImage(&bitmap, 0, 0);
}