VC 呼叫GDI+繪圖
GDI+繪圖功能強大,這裡簡單演示VC呼叫的方法和步驟
主要涉及,調入已有的圖形檔案,在螢幕上繪圖,擷取螢幕上需要的部分,儲存為BMP 或JPG檔案等。
還是直接上程式碼:
//一 首先下載,gdi 有關的標頭檔案和庫檔案
//二 以下部分語句最好放到檔案 StdAfx.h中
#ifndef ULONG_PTR
typedef unsigned long* ULONG_PTR;
#include "Include\\GdiPlus.h"//標頭檔案
using namespace Gdiplus;//名稱空間
#pragma comment(lib, "lib\\gdiplus.lib")//庫檔案
#endif
//三以下功能最好分散到不同的檔案中,這裡為了簡單,集中到一個函式內演示
void CGdiDlg::OnButton1()
{
// TODO: Add your control notification handler code here
//1 初始化,最好在App的 InitInstance()實現
ULONG_PTR m_gdiplusToken;
GdiplusStartupInput gdiplusStartupInput;
GdiplusStartup(&m_gdiplusToken,&gdiplusStartupInput,NULL);
//2 繪圖物件
CDC *pDC=GetDC();
Graphics graphics(pDC->m_hDC);
//-------------------------
//3 字型處理
FontFamily fontFamily2(L"楷體_GB2312");
Font font1(&fontFamily2,20,FontStyleRegular,UnitPixel);
SolidBrush solidBrush(Color(255,0,0,255));
WCHAR str1[]=L"沒有任何優化處理";
graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixel);
graphics.DrawString(str1,(int)wcslen(str1),&font1,PointF(10,10),&solidBrush);
WCHAR str2[]=L"字型優化,但邊不做平滑處理";
graphics.SetTextRenderingHint(TextRenderingHintSingleBitPerPixelGridFit);
graphics.DrawString(str2,(int)wcslen(str2),&font1,PointF(10,30),&solidBrush);
WCHAR str3[]=L"消除走樣,且邊做平滑處理";
graphics.SetTextRenderingHint(TextRenderingHintAntiAliasGridFit);
graphics.DrawString(str3,(int)wcslen(str3),&font1,PointF(10,50),&solidBrush);
//-------------------------
//4 調入jpg圖片
Image image(L"2.jpg");
UINT width=image.GetWidth();
UINT height=image.GetHeight();
//-------------------------
//5 背景刷子
FontFamily fontFamily(L"幼圓");
Font font(&fontFamily,20,FontStyleRegular,UnitPoint);
TextureBrush tBrush(&image);
LinearGradientBrush linGrBrush(Point(30,50), Point(100,50), Color(255, 255, 0, 0), Color(255, 0, 0, 255) );
WCHAR str5[256];
wcscpy(str5, L"圖片刷子");
PointF pointF(30,70);
graphics.DrawString(str5,(int)wcslen(str5),&font,pointF,&tBrush);
wcscpy(str5, L"漸變色刷子");
pointF.Y+=30;
graphics.DrawString(str5,(int)wcslen(str5),&font,pointF,&linGrBrush);
//-------------------------
//6 筆的種類
Pen newPen(Color(255,0,0),3);
HatchBrush newBrush(HatchStyleCross,Color(255,0,266,0),Color(255,0,0,255));
graphics.DrawRectangle(&newPen,260,70,100,60);
graphics.FillRectangle(&newBrush,260,70,100,60);
//-------------------------
//7 調入圖片影像,各種畫法
int posY=160;
//不進行縮放
graphics.DrawImage(&image,10,posY);
//使用低質量的插補演算法
posY+=50;
graphics.SetInterpolationMode(InterpolationModeNearestNeighbor);
graphics.DrawImage(&image,Rect(170,posY,(INT)(0.6*width),(INT)(0.6*height)));
//使用中等質量的插補演算法
posY+=50;
graphics.SetInterpolationMode(InterpolationModeHighQualityBilinear);
graphics.DrawImage(&image,Rect(270,posY,(INT)(0.6*width),(INT)(0.6*height)));
//使用高等質量的插補演算法
posY+=50;
graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
graphics.DrawImage(&image,Rect(370,posY,(INT)(0.6*width),(INT)(0.6*height)));
//-------------------------
//8 圖片的旋轉和拉伸
//1 原點,2 X軸的方法和影象X方向的大小,3 Y軸的方法和影象Y方向的大小
Point points[]={Point(0,0),Point(image.GetWidth(),0),Point(0,image.GetHeight())};
Matrix matrix(1,0,0,1,230,10);//定義一個單位矩陣,座標原點(230,10)
matrix.Rotate(30);//順時針旋轉30度
matrix.Scale(0.63,0.6);//X,Y方向分別乘以0.63 0.6比例因子
matrix.TransformPoints(points,3);//用該矩陣轉換points
graphics.DrawImage(&image,points,3);//平行四邊形,三個點就夠了,第4點系統自動算出
Point newpoints[]={Point(450,10),Point(510,60),Point(350,80) };
graphics.DrawImage(&image,newpoints,3);
//另外旋轉的方法
graphics.TranslateTransform(330,10);//將原點移動到(330,10)
graphics.RotateTransform(60);//順時針旋轉60度
graphics.DrawImage(&image,0,0);
//-------------------------
//9 儲存jpg檔案
//儲存檔案
CRect rect;
GetClientRect(&rect);// ClientToScreen(&rect);
// GetWindowRect(&rect);
SaveScreenJpg("win.jpg", rect,GetDC()) ; //儲存本視窗
SaveScreenJpg("screen.jpg", rect); //儲存整個螢幕
ReleaseDC(pDC);
//-------------------------
//10 退出時,釋放gdi
//最好在App的 ExitInstance()
// Gdiplus::GdiplusShutdown(m_gdiplusToken);
}
// 四這中間使用的圖形格式轉換函式,以及儲存圖形函式
////========================
//VC實現:bmp轉jpg、jpg轉bmp、截圖儲存jpg(GDI+)
int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
{
UINT num = 0; // number of image encoders
UINT size = 0; // size of the image encoder array in bytes
ImageCodecInfo* pImageCodecInfo = NULL;
//2.獲取GDI+支援的影象格式編碼器種類數以及ImageCodecInfo陣列的存放大小
GetImageEncodersSize(&num, &size);
if(size == 0)
return -1; // Failure
//3.為ImageCodecInfo陣列分配足額空間
pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
if(pImageCodecInfo == NULL)
return -1; // Failure
//4.獲取所有的影象編碼器資訊
GetImageEncoders(num, size, pImageCodecInfo);
//5.查詢符合的影象編碼器的Clsid
for(UINT j = 0; j < num; ++j)
{
if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
{
*pClsid = pImageCodecInfo[j].Clsid;
free(pImageCodecInfo);
return j; // Success
}
}
//6.釋放步驟3分配的記憶體
free(pImageCodecInfo);
return -1; // Failure
}
//void SaveFile(Bitmap* pImage, const wchar_t* pFileName)//
void SaveBmpToJpg(Bitmap* pImage, const wchar_t* pFileName)//
{
EncoderParameters encoderParameters;
CLSID jpgClsid;
GetEncoderClsid(L"image/jpeg", &jpgClsid);
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
// Save the image as a JPEG with quality level 100.
ULONG quality;
quality = 80;
encoderParameters.Parameter[0].Value = &quality;
Status status = pImage->Save(pFileName, &jpgClsid, &encoderParameters);
if (status != Ok)
{
wprintf(L"%d Attempt to save %s failed.\n", status, pFileName);
}
}
HBITMAP ReturnHBITMAP(CString FileName)//FileName可能是bmp、dib、png、gif、jpeg/jpg、tiff、emf等檔案的檔名
{
Bitmap tempBmp(FileName.AllocSysString()) ;
Color backColor;
HBITMAP HBitmap;
tempBmp.GetHBITMAP(backColor,&HBitmap);
return HBitmap;
}
////========================
// 將當前螢幕儲存成為jpg圖片
// 引數 quality = jpeg圖象質量
void SaveScreenJpg(CString pszFileName, CRect rect=NULL, CDC *pDC=NULL, int quality=80)
{
//bmp
int left=0, top=0, width=100, height=100;
HDC sourceDC;
HBITMAP hold, hCompBmp;
HDC hMemDC ;
if (pDC==NULL)
{// 為空得到整個螢幕 HWND hwnd = ::GetDesktopWindow();
sourceDC = GetWindowDC(NULL);
left=0; top=0;
width = GetDeviceCaps(sourceDC, HORZRES);
height = GetDeviceCaps(sourceDC, VERTRES);
}
else
{
sourceDC=pDC->m_hDC;
left=rect.left; top=rect.top;
width=rect.Width(); height=rect.Height();
}
hCompBmp = CreateCompatibleBitmap(sourceDC, width, height);
hMemDC = CreateCompatibleDC(sourceDC);
hold = (HBITMAP)::SelectObject(hMemDC, hCompBmp);
BitBlt(hMemDC, 0, 0, width, height, sourceDC, left, top, SRCCOPY);
SelectObject(hMemDC, hold);
Bitmap bit(width, height), bit2(hCompBmp, NULL);
Graphics g(&bit);
// g.ScaleTransform((float)width/wx, (float)height/hy);
g.DrawImage(&bit2, 0, 0);
// --> jpg
CLSID encoderClsid;
EncoderParameters encoderParameters;
encoderParameters.Count = 1;
encoderParameters.Parameter[0].Guid = EncoderQuality;
encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong;
encoderParameters.Parameter[0].NumberOfValues = 1;
encoderParameters.Parameter[0].Value = &quality;
GetEncoderClsid(L"image/jpeg", &encoderClsid);
WCHAR pzWch[MAX_PATH];
for (int k=0;k<pszFileName.GetLength();k++)
pzWch[k]=pszFileName.GetAt(k);
pzWch[k]=0x00;
// bit.Save((LPCWSTR)L"wuchao.jpg", &encoderClsid, &encoderParameters);
bit.Save(pzWch, &encoderClsid, &encoderParameters);
::DeleteObject(hCompBmp);
::DeleteObject(hMemDC);
return;
}
原文轉載自:http://blog.sina.com.cn/s/blog_45eaa01a0102vfhv.html