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