VC6使用GdiPlus绘制png图片

                                          效果图


1 配置Gdiplus

    (1)下载GDI+ for VC6.0 SDK 文件,下载地址  http://pan.baidu.com/s/1pKFEGC7  
   
    (2)新建一个VC6的工程(win32 application).选择典型的hello world.

    (3)把压缩包内“复制里面的内容到VC6工程目录下”文件夹内的内容复制到工程目录下.

    (4)打开自动生成的cpp文件.

    (5)在cpp最前面添加代码:(引用头文件和库,使用GdiPlus命名空间)
#pragma comment(linker, "/subsystem:windows")
#include<windows.h>
#define ULONG_PTR unsigned long
#include "gdiplus/GdiPlus.h"
#pragma comment(lib, "GdiPlus.lib")
using namespace Gdiplus;

    (6)添加两个全局变量(Global Variables),一个是要显示的png,一个是背景图(在上面的下载地址里有这两个图片)
      Image *g_png1;
      Image *g_back1;



    (7)找到WinMain函数,在MyRegisterClass(hInstance);后面添加三行.用于GdiPlus的初始化.
	GdiplusStartupInput gdiplusstartupinput;
	ULONG_PTR gdiplustoken;
	GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);
    (8)在WinMain函数的return之前添加一行,用于关闭程序时GdiPlus的资源回收.
        GdiplusShutdown(gdiplustoken);

2 修改WM_PAINT消息的处理

    (1)找到WndProc函数,在开头的声明部分添加:
	//使用双缓冲防止屏幕闪烁
	HDC hdc_buffer;//缓冲的DC
	HBITMAP m_hSurface;//缓冲的位图


    (2)找到WndProc函数,在switch (message) 的case WM_PAINT:下添加以下代码:
	hdc = BeginPaint(hWnd, &ps);//开始绘图
	hdc_buffer = CreateCompatibleDC(NULL);//创建一个空的DC
	m_hSurface = CreateCompatibleBitmap(hdc, WINDOWS_WIDTH, WINDOWS_HEIGHT);//创建一个与屏幕大小相同的空图片,宽和高可以自己设置
	SelectObject(hdc_buffer, m_hSurface);//选择对象
	OnPaint(hdc_buffer);//这个OnPAINT是自己写的函数
	BitBlt(hdc, 0, 0, 1024, 768, hdc_buffer, 0, 0, SRCCOPY);
	EndPaint(hWnd, &ps);//结束绘画
	DeleteObject(m_hSurface);//释放内存
	DeleteObject(hdc_buffer);//释放内存
	InvalidateRect(hWnd, NULL, FALSE);//重绘所有区域 这样一结束绘图就又会收到系统的WM_PAINT消息 所以一直在重绘
	break;

    (3)添加自己的OnPaint函数
//  FUNCTION:  OnPaint(HDC hdc)
//
//	CREATED BY YOURSELF
//
//	PURPOSE:Paint on the hdc
//
void OnPaint(HDC hdc){
	static double i2;//0-15计数用的 图片中一共有16个子图片
	static double dPos;
	Graphics graphics(hdc);
	graphics.DrawImage(g_back1,0, 0, 0, 0, 800, 600, UnitPixel);//画背景
	graphics.DrawImage(g_png1,(int)dPos, 200, ((int)i2 % 4) * 32, 2 * 32, 32, 32, UnitPixel);//画png
	//参数为 Image* image,INT x,INT y,INT srcx,INT srcy,INT srcwidth,INT srcheight,Unit srcUnit)

	i2=i2+0.04;
	if (i2>15)i2=0;
	dPos+=0.35 ;
	if (dPos > WINDOWS_WIDTH) dPos =0;
}

    (4)编译-运行就OK啦~







附:完整代码(在VC6可直接编译运行(需要配置好环境))


// win32.cpp : Defines the entry point for the application.
//

#define IDI_WIN32	            107
#define IDI_SMALL				108
#define IDC_WIN32	            109

#pragma comment(linker, "/subsystem:windows")
#include <string>
#include <stdlib.h>
#include<windows.h>


#define ULONG_PTR unsigned long
#include "gdiplus/GdiPlus.h"


#pragma comment(lib, "GdiPlus.lib")

using namespace Gdiplus;


#define MAX_LOADSTRING 100
#define WINDOWS_WIDTH 400
#define WINDOWS_HEIGHT 300


//ULONG_PTR        m_gdiplusToken;

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];								// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];								// The title bar text

Image *g_png1;
Image *g_back1;

// Foward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
//LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM);



int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{

	MSG msg;

	MyRegisterClass(hInstance);
	//	Initialize GdiPlus
	GdiplusStartupInput gdiplusstartupinput;
	ULONG_PTR gdiplustoken;
	GdiplusStartup(&gdiplustoken, &gdiplusstartupinput, NULL);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow)) 
	{
		return FALSE;
	}

	//hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WIN32);

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0)) 
	{
		//if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
	//	{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
	//	}

	}
	GdiplusShutdown(gdiplustoken);

	return msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage is only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX); 

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= (WNDPROC)WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			=   LoadIcon(hInstance, (LPCTSTR)IDI_WIN32);
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW);//Grey Color
	wcex.lpszMenuName	=(LPCSTR)IDC_WIN32;
	wcex.lpszClassName	= "WIN32";
	wcex.hIconSm		= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HANDLE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;


   hInst = hInstance; // Store instance handle in our global variable

   hWnd = CreateWindow("WIN32", "win32", WS_OVERLAPPEDWINDOW,
      400, 300, WINDOWS_WIDTH, WINDOWS_HEIGHT, NULL, NULL, hInstance, NULL);


   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  FUNCTION:  OnPaint(HDC hdc)
//
//	CREATED BY YOURSELF
//
//	PURPOSE:Paint on the hdc
//
void OnPaint(HDC hdc){
	static double i2;//0-15计数用的 图片中一共有16个子图片
	static double dPos;
	Graphics graphics(hdc);
	graphics.DrawImage(g_back1,0, 0, 0, 0, 800, 600, UnitPixel);//画背景
	graphics.DrawImage(g_png1,(int)dPos, 200, ((int)i2 % 4) * 32, 2 * 32, 32, 32, UnitPixel);//画png
	//Image* image,INT x,INT y,INT srcx,INT srcy,INT srcwidth,INT srcheight,Unit srcUnit)

	i2=i2+0.04;
	if (i2>15)i2=0;
	dPos+=0.35 ;
	if (dPos > WINDOWS_WIDTH) dPos =0;
}


//
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND	- process the application menu
//  WM_PAINT	- Paint the main window
//  WM_DESTROY	- post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;


	PAINTSTRUCT ps;
	HDC hdc;
	
	//使用双缓冲防止屏幕闪烁
	HDC hdc_buffer;//缓冲的DC
	HBITMAP m_hSurface;//缓冲的位图

//	LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);

	switch (message) 
	{
		case WM_CREATE:
			g_png1 = new Image(L"1.png", FALSE);//载入png
			g_back1 = new Image(L"back.png", FALSE);//载入背景
			break;
			
		case WM_COMMAND:
			
			wmId    = LOWORD(wParam); 
			wmEvent = HIWORD(wParam); 

			switch (wmId){
			case 1:
			default:
			   return DefWindowProc(hWnd, message, wParam, lParam);
			}
			break;
		case WM_PAINT:
			hdc = BeginPaint(hWnd, &ps);//开始绘图
			// TODO: Add any drawing code here...


			hdc_buffer = CreateCompatibleDC(NULL);//创建一个空的DC
			m_hSurface = CreateCompatibleBitmap(hdc, WINDOWS_WIDTH, WINDOWS_HEIGHT);//创建一个与屏幕大小相同的空图片
			SelectObject(hdc_buffer, m_hSurface);//选择对象
			
			OnPaint(hdc_buffer);//这个OnPAINT是自己写的函数
			BitBlt(hdc, 0, 0, 1024, 768, hdc_buffer, 0, 0, SRCCOPY);

			EndPaint(hWnd, &ps);//结束绘画

			DeleteObject(m_hSurface);//释放内存
			DeleteObject(hdc_buffer);//释放内存

			InvalidateRect(hWnd, NULL, FALSE);//重绘所有区域 这样一结束绘图就又会收到系统的WM_PAINT消息 所以一直在重绘

			
			break;
		case WM_DESTROY:
			PostQuitMessage(0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
   }
   return 0;
}

// Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
		case WM_INITDIALOG:
				return TRUE;

		case WM_COMMAND:
			if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
			{
				EndDialog(hDlg, LOWORD(wParam));
				return TRUE;
			}
			break;
	}
    return FALSE;
}




  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GDI+Windows操作系统中的一个图形应用程序接口,可以用于开发2D图形应用程序。使用GDI+绘制图片需要先将图片载入内存,然后再通过GDI+的方法进行绘制。这里介绍一下使用C++代码绘制图片的基本流程。 首先,需要在程序中引用GDI+的头文件和库,然后使用GDI+提供的Image类来读取图片,例如: Image* img = Image::FromFile(L"picture.png"); 这里创建了一个Image对象,并将图片文件“picture.png”从文件中读取到内存中。 然后,可以通过Graphics类的DrawImage方法将图片绘制到指定的位置上,例如: Graphics graphics(hdc); graphics.DrawImage(img, 0, 0); 这里创建了一个Graphics对象,并将Image对象img绘制到坐标(0,0)的位置上。 如果需要对图片进行一些变换,比如旋转、缩放等,可以使用ImageAttributes类和Matrix类来实现。例如,下面的代码将图片旋转了45度: ImageAttributes imageAttr; Matrix matrix; matrix.Rotate(45); imageAttr.SetColorMatrix(&matrix); graphics.DrawImage(img, 0, 0, img->GetWidth(), img->GetHeight(), 0, 0, img->GetWidth(), img->GetHeight(), UnitPixel, &imageAttr); 这里创建了一个ImageAttributes对象,并使用Matrix类将图片旋转了45度,然后通过Graphics的DrawImage方法将旋转后的图片绘制到指定位置上。 综上,使用GDI+绘制图片的基本流程是:载入图片、创建Graphics对象、使用Graphics对象的DrawImage方法将图片绘制到指定位置上。如果需要对图片进行变换,可以使用ImageAttributes类和Matrix类来实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值