请问怎么实现下面这中效果啊。要画的步骤是这样的(背景为黑色):
1、底部的小圆最先画。
2、小圆上面部分是个整体,是两根不同宽度的方头线和四个圆组成,相交点的圆是一个黑色的圆。
在上面整体画的时候不能覆盖掉小圆。请问下怎么实现啊。最好有源代码可以作为参考的。谢谢了!
1、底部的小圆最先画。
2、小圆上面部分是个整体,是两根不同宽度的方头线和四个圆组成,相交点的圆是一个黑色的圆。
在上面整体画的时候不能覆盖掉小圆。请问下怎么实现啊。最好有源代码可以作为参考的。谢谢了!
ms-help://MS.MSDNQTR.v80.chs/MS.MSDN.v80/MS.WIN32COM.v10.en/gdicpp/GDIPlus/usingGDIPlus/alphablendinglinesandfills/usingcompositingmodetocontrolalphablending.htm
Using Compositing Mode to Control Alpha Blending --------------------------------------------------------------------------------There might be times when you want to create an off-screen bitmap that has the following characteristics: Colors have alpha values that are less than 255.
Colors are not alpha blended with each other as you create the bitmap.
When you display the finished bitmap, colors in the bitmap are alpha blended with the background colors on the display device.
To create such a bitmap, construct a blank Bitmap object, and then construct a Graphics object based on that bitmap. Set the compositing mode of the Graphics object to CompositingModeSourceCopy.The following example creates a Graphics object based on a Bitmap object. The code uses the Graphics object along with two semitransparent brushes (alpha = 160) to paint on the bitmap. The code fills a red ellipse and a green ellipse using the semitransparent brushes. The green ellipse overlaps the red ellipse, but the green is not blended with the red because the compositing mode of the Graphics object is set to CompositingModeSourceCopy.Next the code prepares to draw on the screen by calling BeginPaint and creating a Graphics object based on a device context. The code draws the bitmap on the screen twice: once on a white background and once on a multicolored background. The pixels in the bitmap that are part of the two ellipses have an alpha component of 160, so the ellipses are blended with the background colors on the screen.Show Example// Create a blank bitmap.
Bitmap bitmap(180, 100);
// Create a Graphics object that can be used to draw on the bitmap.
Graphics bitmapGraphics(&bitmap);
// Create a red brush and a green brush, each with an alpha value of 160.
SolidBrush redBrush(Color(210, 255, 0, 0));
SolidBrush greenBrush(Color(210, 0, 255, 0));
// Set the compositing mode so that when overlapping ellipses are drawn,
// the colors of the ellipses are not blended.
bitmapGraphics.SetCompositingMode(CompositingModeSourceCopy);
// Fill an ellipse using a red brush that has an alpha value of 160.
bitmapGraphics.FillEllipse(&redBrush, 0, 0, 150, 70);
// Fill a second ellipse using green brush that has an alpha value of 160.
// The green ellipse overlaps the red ellipse, but the green is not
// blended with the red.
bitmapGraphics.FillEllipse(&greenBrush, 30, 30, 150, 70);
// Prepare to draw on the screen.
hdc = BeginPaint(hWnd, &ps);
Graphics* pGraphics = new Graphics(hdc);
pGraphics->SetCompositingQuality(CompositingQualityGammaCorrected);
// Draw a multicolored background.
SolidBrush brush(Color((ARGB)Color::Aqua));
pGraphics->FillRectangle(&brush, 200, 0, 60, 100);
brush.SetColor(Color((ARGB)Color::Yellow));
pGraphics->FillRectangle(&brush, 260, 0, 60, 100);
brush.SetColor(Color((ARGB)Color::Fuchsia));
pGraphics->FillRectangle(&brush, 320, 0, 60, 100);
// Display the bitmap on a white background.
pGraphics->DrawImage(&bitmap, 0, 0);
// Display the bitmap on a multicolored background.
pGraphics->DrawImage(&bitmap, 200, 0);
delete pGraphics;
EndPaint(hWnd, &ps);
The following illustration shows the output of the preceding code. Note that the ellipses are blended with the background, but they are not blended with each other.The preceding code example has the following statement:bitmapGraphics.SetCompositingMode(CompositingModeSourceCopy);
If you want the ellipses to be blended with each other as well as with the background, change that statement to the following:bitmapGraphics.SetCompositingMode(CompositingModeSourceOver);
The following illustration shows the output of the revised code.
--------------------------------------------------------------------------------© 2005 Microsoft Corporation. All rights reserved.
dc.Ellipse(&rcRound);// 画图
dc.EndPath();
CRgn rgn0;
rgn0.CreateFromPath(&dc);
dc.FillRgn(&rgn,&black_brush);// 填充
CClientDC pDC(this);
bool isOK=false; CBrush bkBrush;
CPen pen;
HGDIOBJ orgBrush = NULL;
HGDIOBJ orgPen=NULL; bkBrush.CreateSolidBrush(LPC_BLACK);
orgBrush=SelectObject(pDC,bkBrush);
Rectangle(pDC,0,0,500,500);
pDC.SelectObject(orgBrush); CBrush wtBrush(LPD_WRITE);
orgBrush = pDC.SelectObject(&wtBrush);
pDC.Ellipse(150-10,150-10,150+10,150+10); // 小圆
pDC.SelectObject(orgBrush);
LOGBRUSH lb;
lb.lbStyle = BS_SOLID;
lb.lbColor = LPD_WRITE;
lb.lbHatch = 0;
HPEN hpen;
hpen=ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_INSIDEFRAME,
50,
&lb,
0,
NULL);
orgPen=pDC.SelectObject(hpen); // 组合图
pDC.BeginPath(); // 组合图的图形1
pDC.Ellipse(50-25,300-25,50+25,300+25); // 组合图的图形2
::MoveToEx(pDC,50,300,NULL);
::LineTo(pDC,150,150); // 组合图的图形3
//想这三个组成一个图形,然后贴在原来的那个上面,但是又不覆盖前面那个小圆
//pDC.Ellipse(150-25,150-25,150+25,150+25); //这个想画成黑色的,但是又不覆盖最开始画那个小圆 pDC.EndPath();
//pDC.FillPath();
//pDC.StrokePath();
pDC.StrokeAndFillPath();
pDC.SelectObject(orgPen);
DeleteObject(hpen);
lb.lbColor = LPC_BLACK;
hpen=ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_INSIDEFRAME,
0,
&lb,
0,
NULL);
orgPen=pDC.SelectObject(hpen);
pDC.SelectObject(bkBrush);
//提到外面测试
//// // 组合图的图形3
//pDC.BeginPath();
//pDC.Ellipse(150-25,150-25,150+25,150+25); //这个想画成黑色的,但是又不覆盖最开始画那个小圆
//pDC.EndPath();
////pDC.SelectClipPath(RGN_OR);
//pDC.StrokeAndFillPath(); //CRgn rgn0;
//rgn0.CreateFromPath(&pDC);
//pDC.FillRgn(&rgn0,&bkBrush);// 填充 pDC.SelectObject(orgPen);
pDC.SelectObject(orgBrush); DeleteObject(bkBrush);
DeleteObject(wtBrush);
DeleteObject(orgPen);
DeleteObject(orgBrush);
DeleteObject(hpen);
DeleteObject(pen); DeleteDC(pDC);
不好意思啊,我好像不太明白。
//颜色定义
#define LPD_WRITE RGB(255,255,255)
#define LPC_BLACK RGB(0,0,0)
//创建DC
CClientDC pDC(this);
bool isOK=false;
CBrush bkBrush;
CPen pen;
HGDIOBJ orgBrush = NULL;
HGDIOBJ orgPen=NULL; bkBrush.CreateSolidBrush(LPC_BLACK);
orgBrush=SelectObject(pDC,bkBrush);
Rectangle(pDC,0,0,500,500);
pDC.SelectObject(orgBrush); CBrush wtBrush(LPD_WRITE);
orgBrush = pDC.SelectObject(&wtBrush);
pDC.Ellipse(150-10,150-10,150+10,150+10); // 小圆
pDC.SelectObject(orgBrush);
LOGBRUSH lb;
lb.lbStyle = BS_SOLID;
lb.lbColor = LPD_WRITE;
lb.lbHatch = 0;
HPEN hpen;
hpen=ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_INSIDEFRAME,
50,
&lb,
0,
NULL);
orgPen=pDC.SelectObject(hpen); // 组合图
pDC.BeginPath(); // 组合图的图形1
pDC.Ellipse(50-25,300-25,50+25,300+25); // 组合图的图形2
::MoveToEx(pDC,50,300,NULL);
::LineTo(pDC,150,150); // 组合图的图形3
//想这三个组成一个图形,然后贴在原来的那个上面,但是又不覆盖前面那个小圆
//pDC.Ellipse(150-25,150-25,150+25,150+25); //这个想画成黑色的,但是又不覆盖最开始画那个小圆 pDC.EndPath();
//pDC.FillPath();
//pDC.StrokePath();
pDC.StrokeAndFillPath();
pDC.SelectObject(orgPen);
DeleteObject(hpen);
lb.lbColor = LPC_BLACK;
hpen=ExtCreatePen(PS_GEOMETRIC|PS_SOLID|PS_ENDCAP_FLAT|PS_INSIDEFRAME,
0,
&lb,
0,
NULL);
orgPen=pDC.SelectObject(hpen);
pDC.SelectObject(bkBrush);
//提到外面测试
//// // 组合图的图形3
//pDC.BeginPath();
//pDC.Ellipse(150-25,150-25,150+25,150+25); //这个想画成黑色的,但是又不覆盖最开始画那个小圆
//pDC.EndPath();
////pDC.SelectClipPath(RGN_OR);
//pDC.StrokeAndFillPath(); //CRgn rgn0;
//rgn0.CreateFromPath(&pDC);
//pDC.FillRgn(&rgn0,&bkBrush);// 填充 pDC.SelectObject(orgPen);
pDC.SelectObject(orgBrush); DeleteObject(bkBrush);
DeleteObject(wtBrush);
DeleteObject(orgPen);
DeleteObject(orgBrush);
DeleteObject(hpen);
DeleteObject(pen); DeleteDC(pDC);
不透明 ,不能 贴 , 会 覆盖。
要 path 里 一次 画完
pDC.Ellipse(50-25,300-25,50+25,300+25);
这时 pen 已经=50, 这个 园 不能画 !
CRgn rgnSmBall;
rgnSmBall.CreateEllipticRgn(150-10,150-10,150+10,150+10);
dc.FillRgn(&rgnSmBall,CBrush::FromHandle((HBRUSH)GetStockObject(WHITE_BRUSH))); CRgn rgnBkBall;
rgnBkBall.CreateEllipticRgn(150-25,150-25,150+25,150+25);
rgnBkBall.CombineRgn(&rgnBkBall,&rgnSmBall,RGN_XOR);
dc.FillRgn(&rgnBkBall,CBrush::FromHandle((HBRUSH)GetStockObject(GRAY_BRUSH)));
const int nWidth=400,nHeight=400; CDC MemDC;
CDC tpMemDC; CBitmap MemBitmap;
CBitmap tpBitmap;
MemDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(&MemDC, nWidth*2, nHeight);
tpMemDC.CreateCompatibleDC(NULL);
nWidth-=100;nHeight-=100;
tpBitmap.CreateCompatibleBitmap(&tpMemDC, nWidth*2, nHeight);
tpMemDC.SetWindowOrg(100,100);
CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap);
tpMemDC.SelectObject(&tpBitmap); //设置坐标变换属性
MemDC.SetBkMode(TRANSPARENT);
MemDC.SetMapMode(MM_ANISOTROPIC); //映射模式设定任意比例
tpMemDC.SetBkMode(TRANSPARENT);
tpMemDC.SetMapMode(MM_ANISOTROPIC); //映射模式设定任意比例
MemDC.SetWindowExt(2,1);
MemDC.SetViewportExt(4,1); tpMemDC.SetWindowExt(2,1);
tpMemDC.SetViewportExt(4,1); MemDC.FillSolidRect(0 ,0, nWidth, nHeight, RGB(0, 0, 0)); CBrush wtBrush(LPD_WRITE);
MemDC.SelectObject(wtBrush);
MemDC.Ellipse(180,180,210,210);
CBrush bkBrush(LPC_BLACK);
tpMemDC.SelectObject(wtBrush);
tpMemDC.Ellipse(100,100,300,300); //左上角为100,100
tpMemDC.SelectObject(bkBrush);
tpMemDC.Ellipse(110,110,290,290);
// 左上角
BitBlt(MemDC,100,100, nWidth, nHeight,tpMemDC, 0, 0, SRCPAINT ); MemDC.SelectObject(pOldBit);
CImage img;
img.Attach(MemBitmap);
//img.SetTransparentColor(LPC_BLACK);
//存图
CString path="F:\\1.bmp";
img.Save(path);
img.Detach(); MemBitmap.DeleteObject(); MemDC.DeleteDC();
不要把问题复杂化,先把 MM_TEXT 用好 !再 用 MM_ANISOTROPIC
#define BR_WHITE RGB(255,255,255)
#define BR_BLACK RGB(0,0,0)
#define CENTER_X 195
#define CENTER_Y 195
#define R1 15
#define R2 90
#define R3 100 void CxxxxDlg::OnXXX()
{
// TODO: Add your control notification handler code here
CClientDC dc(this);
// 2 brush
CBrush bkBrush;
bkBrush.CreateSolidBrush(BR_BLACK);
CBrush wtBrush;
wtBrush.CreateSolidBrush(BR_WHITE);
//
HBRUSH orgBrush = NULL;
// draw background
orgBrush=(HBRUSH)SelectObject(dc,bkBrush);
dc.Rectangle(0,0,500,500);
// restore
dc.SelectObject(orgBrush);
// draw a small ball in white color
CRgn rgnSmBall;
rgnSmBall.CreateEllipticRgn(CENTER_X-R1,CENTER_Y-R1,CENTER_X+R1,CENTER_Y+R1);
dc.FillRgn(&rgnSmBall,&wtBrush);
// draw a big ball covers small ball
CRgn rgnBgBall;
rgnBgBall.CreateEllipticRgn(CENTER_X-R3,CENTER_Y-R3,CENTER_X+R3,CENTER_Y+R3);
rgnBgBall.CombineRgn(&rgnBgBall,&rgnSmBall,RGN_XOR);
dc.FillRgn(&rgnBgBall,&wtBrush);
// draw a mid ball also covers small ball
CRgn rgnMdBall;
rgnMdBall.CreateEllipticRgn(CENTER_X-R2,CENTER_Y-R2,CENTER_X+R2,CENTER_Y+R2);
rgnMdBall.CombineRgn(&rgnMdBall,&rgnSmBall,RGN_XOR);
dc.FillRgn(&rgnMdBall,&bkBrush);
}
void CCBlistDlg::OnButton1()
{
////////// Using CreateDIBSection is too slow !
#if 0
ShowWindow(SW_HIDE);
Sleep(0);// compare with Sleep(100) HDC hScrDC = ::GetDC(NULL);
HDC hMemDC = NULL;
int nWidth = GetSystemMetrics(SM_CXSCREEN);
int nHeight = GetSystemMetrics(SM_CYSCREEN);
hMemDC = ::CreateCompatibleDC(hScrDC);
BITMAPINFO bi;
ZeroMemory(&bi, sizeof(BITMAPINFO));
bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bi.bmiHeader.biWidth = nWidth;
bi.bmiHeader.biHeight = nHeight;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biBitCount = 24;
HCURSOR hCursor = GetCursor();
POINT ptCursor;
GetCursorPos(&ptCursor);
ICONINFO IconInfo = {0};
if(GetIconInfo(hCursor, &IconInfo))
{
ptCursor.x -= IconInfo.xHotspot;
ptCursor.y -= IconInfo.yHotspot;
if(NULL != IconInfo.hbmMask)
DeleteObject(IconInfo.hbmMask);
if(NULL != IconInfo.hbmColor)
DeleteObject(IconInfo.hbmColor);
}
BYTE *lpBitmapBits = NULL;
HBITMAP bitmap = ::CreateDIBSection(hMemDC, &bi, DIB_RGB_COLORS, (LPVOID*)&lpBitmapBits, NULL, 0);
HGDIOBJ oldbmp = ::SelectObject(hMemDC, bitmap);
::BitBlt(hMemDC, 0, 0, nWidth, nHeight, hScrDC, 0, 0, SRCCOPY);
DrawIconEx(hMemDC, ptCursor.x, ptCursor.y, hCursor, 0, 0, 0, NULL, DI_NORMAL | DI_COMPAT);
int rest = nWidth*3 %4 ; BITMAPFILEHEADER bh;
ZeroMemory(&bh, sizeof(BITMAPFILEHEADER));
bh.bfType = 0x4d42; //bitmap
bh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bh.bfSize = bh.bfOffBits + (nWidth*3+rest)*nHeight;
CFile file;
if(file.Open("2.bmp", CFile::modeCreate | CFile::modeWrite))
{
file.Write(&bh, sizeof(BITMAPFILEHEADER));
file.Write(&(bi.bmiHeader), sizeof(BITMAPINFOHEADER));
// file.Write(lpBitmapBits, 3 * nWidth * nHeight);
file.Write(lpBitmapBits, (nWidth*3+rest)*nHeight);
file.Close();
}
::SelectObject(hMemDC, oldbmp);
#ifndef TEST// error ! bitmap seperated with lpBitmapBits ?
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,bitmap);
CloseClipboard();
#endif
::DeleteObject(bitmap);
::DeleteObject(hMemDC);
::ReleaseDC(NULL, hScrDC);
ShowWindow(SW_SHOW);
////////// Using CreateCompatibleBitmap is more fast !
#else
ShowWindow(SW_HIDE);
Sleep(100); CDC *pDC;
pDC = GetDesktopWindow()->GetDC();
if(pDC == NULL) return;
int BitPerPixel = pDC->GetDeviceCaps(BITSPIXEL);
int Width = pDC->GetDeviceCaps(HORZRES);
int Height = pDC->GetDeviceCaps(VERTRES);
CDC memDC;
if(memDC.CreateCompatibleDC(pDC) == 0) return;
CBitmap memBitmap, *oldmemBitmap;
if(memBitmap.CreateCompatibleBitmap(pDC, Width, Height) == NULL) return;
#ifndef TEST// OK
OpenClipboard();
EmptyClipboard();
SetClipboardData(CF_BITMAP,memBitmap);
CloseClipboard();
#endif
oldmemBitmap = memDC.SelectObject(&memBitmap); if(memDC.BitBlt(0, 0, Width, Height, pDC, 0, 0, SRCCOPY) == 0) return;
BITMAP bmp;
memBitmap.GetBitmap(&bmp);
//计算24位图像每行的字节数
int BytesPerLine = 3 * bmp.bmWidth;
while(BytesPerLine % 4 != 0)
BytesPerLine ++;
BITMAPINFOHEADER bih = {0};//位图信息头
bih.biBitCount = 24;//每个像素字节大小
bih.biCompression = BI_RGB;
bih.biHeight = bmp.bmHeight;//高度
bih.biPlanes = 1;
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biSizeImage = BytesPerLine * bmp.bmHeight;//图像数据大小
bih.biWidth = bmp.bmWidth;//宽度
BITMAPFILEHEADER bfh = {0};//位图文件头
bfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);//到位图数据的偏移量
bfh.bfSize = bfh.bfOffBits + bih.biSizeImage;//文件总的大小
bfh.bfType = (WORD)0x4d42;
FILE *fp = fopen("xxxx.bmp", "w+b");
fwrite(&bfh, 1, sizeof(BITMAPFILEHEADER), fp);//写入位图文件头
fwrite(&bih, 1, sizeof(BITMAPINFOHEADER), fp);//写入位图信息头
byte *p = new byte[bih.biSizeImage];
//获取当前32位图像数据
GetDIBits(memDC.m_hDC,
(HBITMAP) memBitmap.m_hObject,
0,
Height,
p,
(LPBITMAPINFO) &bih,
DIB_RGB_COLORS);
//只取rgb值,存入文件
byte b = 0;//用于填充
for(int i = 0 ; i < bmp.bmWidth * bmp.bmHeight ; i ++)
{
//32位位图图像的格式为:Blue, Green, Red, Alpha
fwrite(&(p[i * 3]), 1, 3, fp);
if(i % bmp.bmWidth == bmp.bmWidth - 1)//填充字节
{
for(int k = 0 ; k < (BytesPerLine - bmp.bmWidth * 3) ; k ++)
fwrite(&b, sizeof(byte), 1, fp);
}
}
delete [] p;
fclose(fp);
memDC.SelectObject(oldmemBitmap);
//
ShowWindow(SW_SHOW);
#endif
AfxMessageBox("xxxx.bmp Created!");
// ShowWindow(SW_MINIMIZE);
}