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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值