load a PNG file from memory

Is there any easy way to load a PNG file from memory (as opposed to from the hard drive) in VC++?

Try using resource files to store the PNG file data.

Going down that route, resource files only directly support BMP as far as imaging goes so you might want to consider that to make your life easier.
Hi

You can use gdiplus to load a png file from a resource or memory using a stream.

Ill post my whole example file. And hopefully it will give you the info that your after.

you will need to add 'kernel32.lib' 'ole32.lib' & 'gdiplus.lib' to your linking

Make sure you have GdiplusStartup(&token,&startupInput,NULL); in your initialization

I have an output in WM_PAINT but you could just as well write to an offscreen DC

The rest of the work is done in getImage()

Please post any follow up questions.

resource.rc
 
PIC1	RCDATA	test.png


resource.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#ifndef	RESOURCE_H
#define	RESOURCE_H

#include <windows.h>
#include <gdiplus.h>

using namespace Gdiplus;

// standard window methods and properties
/////////////////////////////////////////
	bool	regWindow();
	bool	makeWindow();

	LRESULT	CALLBACK	wndProc(HWND hWnd,UINT uMsg,WPARAM wParam,
				LPARAM lParam);

	
	HINSTANCE	hInst;
	HWND		hwnd;
	MSG		msg;

	WNDCLASSEX	wc;

//////////////////////////////////////////

	void	getImage();

	HGLOBAL		hGlobal;
	LPSTREAM	pStream;

	Image*		ourImage;

	GdiplusStartupInput startupInput;
	ULONG_PTR			token;

#endif 


resource.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include "resource.h"

using namespace Gdiplus;

int	WINAPI	WinMain(HINSTANCE hInstance,HINSTANCE pInstance,
			LPSTR pCmdLine,int cmdShow)
{ 
	hInst = hInstance;
 
	if (!regWindow())
	{
		return(0);
	}

	if (!makeWindow())
	{
		return(0);
	}

	while (GetMessage(&msg,NULL,NULL,NULL))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	return(0);
}

bool	regWindow()
{
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = (WNDPROC) &wndProc;	
	wc.cbClsExtra = NULL;
	wc.cbWndExtra = NULL;
	wc.hInstance  = hInst;
	wc.hIcon = NULL;
	wc.hCursor = LoadCursor(NULL,IDC_ARROW);
	wc.hbrBackground = (HBRUSH) COLOR_APPWORKSPACE + 1;
	wc.lpszMenuName = NULL;
	wc.lpszClassName = "resourceTest";
	wc.hIconSm = NULL;

	return(RegisterClassEx(&wc));
}

bool	makeWindow()
{
	HWND	win1 = CreateWindow("resourceTest","Resource Image Test",
			WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU,
			CW_USEDEFAULT,0,400,300,NULL,NULL,hInst,NULL);

	if (win1 == NULL)
	{
		return(false);
	}
	else
	{
		ShowWindow(win1,SW_SHOW);
		UpdateWindow(win1);

		return(true);
	}
}

LRESULT		CALLBACK	wndProc(HWND hWnd,UINT uMsg,WPARAM wParam,
					LPARAM lParam)
{
	HDC			hdc;
	PAINTSTRUCT	ps;
	Graphics*	graphics;

	char*	temp;

	switch(uMsg)
	{
	case	WM_DESTROY:

		PostQuitMessage(0);
		break;

	case	WM_CREATE:

		hwnd = hWnd;

		GdiplusStartup(&token,&startupInput,NULL);

		getImage();

		break;

	case	WM_PAINT:

		hdc = BeginPaint(hWnd,&ps);

			graphics = new Graphics(hdc);

			graphics->DrawImage(ourImage,5,5);

			delete(graphics);

		EndPaint(hWnd,&ps);

	default:

		return(DefWindowProc(hWnd,uMsg,wParam,lParam));
	}

	return(0);
}

void	getImage()
{
	HRSRC	hRsrc = FindResource(NULL,"PIC1",RT_RCDATA);

	HGLOBAL	hGlob1 = LoadResource(NULL,hRsrc);

	int	size = SizeofResource(NULL,hRsrc);

	hGlobal = GlobalAlloc(GMEM_FIXED,size);

	LPVOID	resPtr = LockResource(hGlob1);

	memcpy(hGlobal,resPtr,size);

	FreeResource(hGlob1);

	//create stream

	CreateStreamOnHGlobal(hGlobal,true,&pStream);

	ourImage = new Image(pStream,false);

}


Hope this helps
Shredded
Topic archived. No new replies allowed.