GDI+在内存中绘图
来源:互联网 发布:linux vnc地址 编辑:程序博客网 时间:2024/05/20 07:31
为了防止画图闪烁,一般先将图像画制到内存中,再复制到界面上去。C++builder中的控件或窗体本身有双缓冲功能,即本身具有这种功能。但是对于GDI+来说,并没有封装成到TCanvas类中。因此用GDI+来绘图时,会存在闪烁的现象,那么可以用内存绘图来解决。
简单的内存绘图类如下:
#ifndef __BCBMEN__#define __BCBMEM__#include <math.h> #include <algorithm>using std::min;using std::max;#include "gdiplus.h"#pragma warn -inl#pragma warn -8022using namespace Gdiplus;class MemCanvas{ private: HDC m_hdcMemory; //内存句柄 HDC hdcTemp; //设备上下文句柄 HBITMAP hBitMap; //位图句柄 TSize m_size; public: HDC __fastcall CreateMemCanvas(int width,int height); __fastcall ~MemCanvas(); void __fastcall CanvasCopy(TCanvas * Img,TRect rc,int left,int top,int mode);};HDC __fastcall MemCanvas::CreateMemCanvas(int width,int height){ //============================== hdcTemp = GetDC(0);//设备上下文环境句柄 m_hdcMemory = CreateCompatibleDC(hdcTemp);//内存环境句柄 //该函数创建与指定的设备环境相关的设备兼容的位图 hBitMap = CreateCompatibleBitmap(hdcTemp,width,height); SelectObject(m_hdcMemory, hBitMap);//该函数选择一对象到指定的设备上下文环境中 return m_hdcMemory;}__fastcall MemCanvas::~MemCanvas(){ ReleaseDC(0, hdcTemp); hdcTemp = NULL; DeleteObject(hBitMap); DeleteDC(m_hdcMemory); m_hdcMemory = NULL;}
//复制到指定TCanvas中,mode = SRCCOPYvoid __fastcall MemCanvas::CanvasCopy(TCanvas * Canvas,TRect rc,int left,int top,int mode){ BitBlt(Canvas->Handle, rc.Left, rc.Top, rc.Width(), rc.Height(), m_hdcMemory, left, top, mode);}#endif
窗体的.h文件内容如下:
#ifndef Unit1H#define Unit1H//---------------------------------------------------------------------------#include <Classes.hpp>#include <Controls.hpp>#include <StdCtrls.hpp>#include <Forms.hpp>#include <ExtCtrls.hpp>#include "MemCanvas.h"//---------------------------------------------------------------------------class TForm1 : public TForm{__published:// IDE-managed Components TTimer *Timer1; TImage *Image1; void __fastcall Timer1Timer(TObject *Sender);private:// User declarations ULONG_PTR GdiplusToken; //GDI初始化相关 Gdiplus::GdiplusStartupInput GdiplusStartupInput;public:// User declarations __fastcall TForm1(TComponent* Owner); __fastcall ~TForm1(void); HDC m_hdcMemory; //内存句柄 MemCanvas * p1; Gdiplus::Graphics *g;};//---------------------------------------------------------------------------extern PACKAGE TForm1 *Form1;//---------------------------------------------------------------------------#endif在.cpp中调用如下:
//---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include "Unit1.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"TForm1 *Form1;//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner){ Image1->Parent->DoubleBuffered = true; GdiplusStartup(&GdiplusToken, &GdiplusStartupInput, NULL); // 初始化GDI+ //============================== p1= new MemCanvas; //创建内存位图对象 m_hdcMemory = p1->CreateMemCanvas(450,265);//创建内存位图句柄 g= new Gdiplus::Graphics(m_hdcMemory);//创建GDI+对象 //==================================}//---------------------------------------------------------------------------__fastcall TForm1::~TForm1(void) { g->ReleaseHDC(m_hdcMemory); GdiplusShutdown(GdiplusToken); // 关闭GDI+ delete p1;}//---------------------------------------------------------------------------void __fastcall TForm1::Timer1Timer(TObject *Sender){ const static int OX = 200, OY = 200;const static REAL C = 140;const static REAL PI = 3.14;static REAL offset = 0;POINT p[4];REAL k[4]; g->Clear(13369376); //==============================// 生成正文形四角的新坐标值for (int i=0; i < 4; i++){ k[i] = offset + (PI / 2) * i; p[i].x = (int)OX + C*sin(k[i]); p[i].y = (int)OY + C*cos(k[i]);}g->SetSmoothingMode(SmoothingModeHighQuality); //高画质、低速// 重新填充背景SolidBrush brush(Color::Color(100,0,0));//画刷Pen pen(Color::Color(255, 0, 0), 1);//画笔g->FillRectangle(&brush, 0, 0, ClientWidth, ClientHeight); //画矩形Gdiplus::Point point1(p[0].x, p[0].y);//设置点坐标Gdiplus::Point point2(p[1].x, p[1].y);Gdiplus::Point point3(p[2].x, p[2].y);Gdiplus::Point point4(p[3].x, p[3].y);Gdiplus::Point point5(p[0].x, p[0].y);// 在新坐标绘画正方形Gdiplus::Point points[] = {point1, point2, point3, point4, point5};g->DrawLines(&pen, points, 5);//画线offset += 0.1; //内存位图类方法 TRect rc(0,0,600,600); //将内存中的位图复制到指定画布 p1->CanvasCopy(Image1->Canvas,rc,0,0,cmSrcCopy); Image1->Repaint();//刷新画布}//---------------------------------------------------------------------------
上述代码参考过妖哥的一些代码。在C++builder6中编译通过。
0 0
- GDI+在内存中绘图
- 在内存中绘图
- 在内存中绘图
- VC在内存中绘图
- VC中使用GDI+在内存转换图片类型
- 使用IStream和GDI+在内存中实现图像格式转换
- VC++控制台应用程序下使用GDI在内存中画图
- vc6.0使用gdi+在内存中绘图并将其保存为bmp,jpg,gif,png等格式的图片
- vc6.0使用gdi+在内存中绘图并将其保存为bmp,jpg,gif,png等格式的图片
- 在内存绘图并保存为图片格式
- 利用HDC在内存上绘图
- 利用HDC在内存上绘图
- MFC中GDI绘图
- 数据在内存中各种形式
- 在内存中加载DLL
- 对象在内存中结构
- float在内存中存储
- Bitmap在内存中加载
- 最适合和孩子一起看的100部BBC经典纪录片
- cocos2dx3.2学习之路之锚点
- EBS OAF开发中部署OAF项目
- 键盘字符16进制码表,字符八进制 十进制 十六进制 对照表
- 扩展Js startWith函数,类似Java中的startsWith
- GDI+在内存中绘图
- ElasticSearch 简单入门
- Web Office Apps 按照微软官方的例子部署后 仅能预览 excel 其他格式全都无法预览
- 【转】windows下抓本机环回包的方法
- Android Studio 如何导入第三方jar包(整理)
- 2014/11/06 Oracle触发器初步
- C#关机小程序源码
- git patch 使用
- MySQL事务示例