CMyMemDC.h
#pragma once #include "afxwin.h" #include "atlimage.h" class CMyMemDC : public CDC { public: CMyMemDC(); CMyMemDC(int cx, int cy, CDC* pDC = NULL); CMyMemDC(UINT nResID, CDC* pDC, LPCTSTR lpTyp = _T("BMP")); ~CMyMemDC(); private: CSize m_size; private: BOOL LoadCImageFromResourse(CImage *pImage, UINT nResID, LPCTSTR lpTyp); public: BOOL Create(int cx, int cy, CDC* pDC = NULL); BOOL Create(UINT nResID, CDC* pDC, LPCTSTR lpTyp = _T("BMP")); void BitTrans(int xDest,int yDest,int nDestWidth,int nDestHeight, CDC* pDC,int xSrc,int ySrc,COLORREF crTrans); void StretchTrans(int xDest, int yDest, int nDestWidth, int nDestHeight,CDC* pDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, COLORREF crTrans); UINT GetWidth(); UINT GetHeight(); };
#include "stdafx.h" #include "MyMemDC.h" CMyMemDC::CMyMemDC() { m_size.cx = m_size.cy = 0; } CMyMemDC::CMyMemDC(int cx, int cy, CDC* pDC) { Create(cx, cy, pDC); } CMyMemDC::CMyMemDC(UINT nResID, CDC* pDC, LPCTSTR lpTyp) { Create(nResID, pDC, lpTyp); } CMyMemDC::~CMyMemDC() { if (!GetSafeHdc()) return; CBitmap* pBitmap = GetCurrentBitmap(); if (pBitmap) pBitmap->DeleteObject(); DeleteDC(); } BOOL CMyMemDC::Create(int cx, int cy, CDC* pDC) { CBitmap bmp; if (!bmp.CreateCompatibleBitmap(pDC,cx,cy)) return FALSE; m_size.cx = cx; m_size.cy = cy; CreateCompatibleDC(pDC); SelectObject(&bmp); return TRUE; } BOOL CMyMemDC::Create(UINT nResID, CDC* pDC, LPCTSTR lpTyp) { CImage img; LoadCImageFromResourse(&img, nResID, lpTyp); CBitmap bmp; if (!bmp.CreateCompatibleBitmap(pDC, img.GetWidth(), img.GetHeight())) return FALSE; m_size.cx = img.GetWidth(); m_size.cy = img.GetHeight(); CreateCompatibleDC(pDC); SelectObject(&bmp); img.BitBlt(m_hDC, 0, 0, m_size.cx, m_size.cy, 0, 0, SRCCOPY); return TRUE; } void CMyMemDC::BitTrans(int xDest, int yDest, int nDestWidth, int nDestHeight, CDC* pDC, int xSrc, int ySrc, COLORREF crTrans) { CMyMemDC dcImage(nDestWidth, nDestHeight,pDC); CBitmap bmpMask; bmpMask.CreateBitmap(nDestWidth, nDestHeight, 1, 1, NULL); CDC dcMask; dcMask.CreateCompatibleDC(pDC); dcMask.SelectObject(&bmpMask); dcImage.BitBlt(0,0, nDestWidth, nDestHeight,this, xSrc, ySrc,SRCCOPY); dcImage.SetBkColor(crTrans); dcMask.BitBlt(0, 0, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCCOPY); dcImage.SetBkColor(RGB(0,0,0)); dcImage.SetTextColor(RGB(255,255,255)); dcImage.BitBlt(0, 0, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND); pDC->SetBkColor(RGB(255, 255, 255)); pDC->SetTextColor(RGB(0, 0, 0)); pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND); pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCPAINT); dcMask.DeleteDC(); bmpMask.DeleteObject(); } void CMyMemDC::StretchTrans(int xDest, int yDest, int nDestWidth, int nDestHeight,CDC* pDC, int xSrc, int ySrc, int nSrcWidth, int nSrcHeight, COLORREF crTrans) { CMyMemDC dcImage(nDestWidth, nDestHeight, pDC); CBitmap bmpMask; bmpMask.CreateBitmap(nDestWidth, nDestHeight, 1, 1, NULL); CDC dcMask; dcMask.CreateCompatibleDC(pDC); dcMask.SelectObject(&bmpMask); if (nDestWidth == nSrcWidth && nDestHeight == nSrcHeight) { dcImage.BitBlt(0, 0, nDestWidth, nDestHeight, this, xSrc, ySrc, SRCCOPY); } else { dcImage.SetStretchBltMode(STRETCH_HALFTONE); dcImage.StretchBlt(0, 0, nDestWidth, nDestHeight, this, xSrc, ySrc, nSrcWidth, nSrcHeight, SRCCOPY); } dcImage.SetBkColor(crTrans); dcMask.BitBlt(0, 0, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCCOPY); dcImage.SetBkColor(RGB(0, 0, 0)); dcImage.SetTextColor(RGB(255, 255, 255)); dcImage.BitBlt(0, 0, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND); pDC->SetBkColor(RGB(255, 255, 255)); pDC->SetTextColor(RGB(0, 0, 0)); pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcMask, 0, 0, SRCAND); pDC->BitBlt(xDest, yDest, nDestWidth, nDestHeight, &dcImage, 0, 0, SRCPAINT); dcMask.DeleteDC(); bmpMask.DeleteObject(); } BOOL CMyMemDC::LoadCImageFromResourse(CImage *pImage, UINT nResID, LPCTSTR lpTyp) { if (pImage == NULL) return FALSE; pImage->Destroy(); HMODULE hModule = AfxGetInstanceHandle(); if (lpTyp == _T("BMP")) { pImage->LoadFromResource(hModule, MAKEINTRESOURCE(nResID)); return TRUE; } // 查找资源 HRSRC hRsrc = ::FindResource(hModule, MAKEINTRESOURCE(nResID), lpTyp); if (hRsrc == NULL) return FALSE; // 加载资源 HGLOBAL hImgData = ::LoadResource(hModule, hRsrc); if (hImgData == NULL) { ::FreeResource(hImgData); return FALSE; } // 锁定内存中的指定资源 LPVOID lpVoid = ::LockResource(hImgData); LPSTREAM pStream = NULL; DWORD dwSize = ::SizeofResource(hModule, hRsrc); HGLOBAL hNew = ::GlobalAlloc(GHND, dwSize); LPBYTE lpByte = (LPBYTE)::GlobalLock(hNew); ::memcpy(lpByte, lpVoid, dwSize); // 解除内存中的指定资源 ::GlobalUnlock(hNew); // 从指定内存创建流对象 HRESULT ht = ::CreateStreamOnHGlobal(hNew, TRUE, &pStream); if (ht != S_OK) { GlobalFree(hNew); } else { // 加载图片 pImage->Load(pStream); if (pImage->GetBPP() == 32) //确认该图片包含Alpha通道 { for (int i = 0; i < pImage->GetWidth(); i++) for (int j = 0; j < pImage->GetHeight(); j++) { byte* pByte = (byte*)pImage->GetPixelAddress(i, j); pByte[0] = pByte[0] * pByte[3] / 255; pByte[1] = pByte[1] * pByte[3] / 255; pByte[2] = pByte[2] * pByte[3] / 255; } } GlobalFree(hNew); } // 释放资源 ::FreeResource(hImgData); return TRUE; } UINT CMyMemDC::GetWidth() { return m_size.cx; } UINT CMyMemDC::GetHeight() { return m_size.cy; }
用法:
CPaintDC dc(this); CRect rc; GetClientRect(rc); dc.BitBlt(0, 0, rc.Width(), rc.Height(), &m_dc, 0, 0, SRCCOPY); m_dc.BitTrans(100, 0, rc.Width(), rc.Height(), &dc,0, 0, RGB(0,0,0)); m_dc.StretchTrans(0, 0, rc.Width()-200, rc.Height()-200, &dc, 0, 0, m_dc.GetWidth(),m_dc.GetHeight(), RGB(0, 0, 0)); CDialog::OnPaint();