【HSP3】Mem_Picload Ver 1.01

GDI+ を使用してメモリから画像を表示する Mem_Picload の Ver 1.01 です。解放されないバグを修正しました。

GDI+ を使用してメモリから画像を表示する Mem_Picload の Ver 1.01 です。解放されないバグを修正しました。

/***************************************************************
   [ Mem_Picload ]                             Version  1.01
   
    - BMP, GIF, JPEG, PNG, TIFF など GDI+ がサポートするファイル
    をメモリ上から開くことが出来るようになります。
    
    ※ Windows XP 以前は 再配布可能 GDI+「gdiplus.dll」が必要

    HSP3 のパックファイルに入れても読み取ることが可能

    作者 : イノビア ( http://homepage2.nifty.com/MJHS/ )

    ■ 自由に組み込み可、改造大歓迎、改造した物公開OK
 ***************************************************************/

#module _mem_pic_

#define IID_IStream  "{0000000C-0000-0000-C000-000000000046}"
#define CLSID_Stream "{00000320-0000-0000-C000-000000000046}"
#usecom IStream IID_IStream CLSID_Stream

#uselib "kernel32"
#cfunc GlobalAlloc "GlobalAlloc" int,int
#cfunc GlobalLock "GlobalLock" int
#func GlobalUnlock "GlobalUnlock"int
#func GlobalFree "GlobalFree"int

#uselib "ole32"
#cfunc CreateStreamOnHGlobal "CreateStreamOnHGlobal" int,int,var

#uselib "gdiplus"
#func GdiplusStartup "GdiplusStartup" var,var,int
#func GdipCreateFromHDC "GdipCreateFromHDC" int,var
#func GdipDeleteGraphics "GdipDeleteGraphics" var
#func GdipGetImageWidth "GdipGetImageWidth"	int,int
#func GdipGetImageHeight "GdipGetImageHeight" int,int
#func GdipDrawImage "GdipDrawImageI" var,var,int,int
#func GdipDrawImage2 "GdipDrawImage" var,var,int,int
#func GdipDrawImageR "GdipDrawImageRectI" var,var,int,int,int,int
#func GdipDisposeImage "GdipDisposeImage" var
#func GdiplusShutdown "GdiplusShutdown" var
#func GdipLoadImageFromStream "GdipLoadImageFromStream" comobj,var

#deffunc mem_picinit int _cbuf
	cbuf = _cbuf
	if cbuf = 0 : cbuf = 32
	dimtype pstm, vartype("comobj"), cbuf
	dim _id, cbuf
	dim token, cbuf
	dim hGlobal, cbuf
	dim ppstm, cbuf
	dim ppImg, cbuf
	pGraphics = 0
return

#deffunc mem_picload int id, var data, int size

	if _id(id) != 0 : return -2			// ID使用中
	if size <= 0 : return -3			// ファイルサイズ異常
	if id >= cbuf : return -4			// 管理できるのは 0 ~ cbuf まで

	//初期化
	dim GdiplusStartupInput, 4
	GdiplusStartupInput = 1, 0, 0, 0
	GdiplusStartup token(id), GdiplusStartupInput, 0

	hGlobal(id) = GlobalAlloc(2, size+1)
	dupptr tmp, GlobalLock(hGlobal.id), size, 2
	memcpy tmp, data, size
	GlobalUnLock hGlobal(id)

	if CreateStreamOnHGlobal(hGlobal(id), 1, ppstm(id)) = 0{
		newcom pstm(id), IStream, -1, ppstm(id)
		GdipLoadImageFromStream pstm(id), ppImg(id)
	}
	_id(id) = 1
return
#deffunc mem_picgetsize int id, var x, var y

	if _id(id) = 0 : return -1		// 未確保ID

	dupptr pImg, ppImg(id), 4
	GdipGetImageWidth ppImg(id), varptr(x)
	GdipGetImageHeight ppImg(id), varptr(y)
	
return

#deffunc mem_picrectscreen int id, int x1, int y1, int x2, int y2 

	if _id(id) = 0 : return -1		//未確保ID

	dupptr pImg, ppImg(id), 4
	GdipCreateFromHDC hdc, pGraphics
	dupptr Graphics, pGraphics, 4
	GdipDrawImageR Graphics, pImg, x1, y1, x2, y2
	GdipDeleteGraphics Graphics
	redraw 1
return

#deffunc mem_pictoscreen int id, int x1, int y1

	if _id(id) = 0 : return -1		//未確保ID

	dupptr pImg, ppImg(id), 4
	GdipCreateFromHDC hdc, pGraphics
	dupptr Graphics, pGraphics, 4
	GdipDrawImage Graphics, pImg, x1, y1
	GdipDeleteGraphics Graphics
	redraw 1
	
return

#deffunc mem_picfree int id

	if _id(id) = 0 : return -1		//未確保ID

	dupptr pImg,ppImg(id), 4
	GdipDisposeImage pImg
	GlobalFree hGlobal(id)
	GdiplusShutdown token(id)

	delcom pstm(id)
	
	_id(id) = 0
return
#deffunc picload_ex str fname, var x, var y

	exist fname
	if strsize = -1 : return -1
	if varptr(GdiplusStartup) = 0 : return -2	// GDI+が使用できなかった

	size = strsize

	mem_picinit 1

	notesel buf
	noteload fname
	
	mem_picload 0, buf, size
	mem_picgetsize 0, x, y
	mem_picrectscreen 0, 0, 0, x, y
	mem_picfree 0
	sdim buf, 64

return
#deffunc picload_ex2 str fname,int _x1, int _y1,int _x2, int _y2, var x, var y

	exist fname
	if strsize = -1 : return -1
	if varptr(GdiplusStartup) = 0 : return -2	// GDI+が使用できなかった

	size = strsize

	mem_picinit 1

	notesel buf
	noteload fname
	
	mem_picload 0, buf, size
	mem_picgetsize 0, x, y
	mem_picrectscreen 0, _x1, _y1, _x2, _y2
	mem_picfree 0
	sdim buf, 64

return
#global

/*
------------------------------------------------------------------------
	mem_picinit p1(32)

	mem_ 関連の命令を初期化します。初回のみ実行してください。
	
	p1 は 利用可能なID 範囲を決めます。
	何も書かないと、デフォルトで 32 になります。

------------------------------------------------------------------------
	mem_picload p1,p2,p3

	メモリ上にある画像ファイルを読み込みます。
	BMP, GIF, JPEG, PNG, TIFF などが読み込み可能です。
	
	p1 は ID を指定します。
	p2 は データの変数を指定します。
	p3 は データの大きさ(サイズ)を指定します。

------------------------------------------------------------------------
	mem_picgetsize p1,p2,p3

	画像のサイズ(縦横)を取得します。
	
	p1 は mem_picloadで指定したIDを入れます。
	p2 は 画像の X サイズを入れるための変数を指定。
	p3 は 画像の Y サイズを入れるための変数を指定。

------------------------------------------------------------------------
	mem_pictoscreen p1,p2,p3

	画像をHSPの画面に転送します。
	等倍のまま転送されます。
	
	p1 は mem_picloadで指定したIDを入れます。
	p2 は 表示する位置(左上 X 座標)
	p3 は 表示する位置(左上 Y 座標)
	
------------------------------------------------------------------------
	mem_picrectscreen p1,p2,p3,p4,p5

	画像をHSPの画面に転送します。
	変形して転送可能です。
	
	p1 は mem_picloadで指定したIDを入れます。
	p2 は 表示する位置(左上 X 座標)
	p3 は 表示する位置(左上 Y 座標)
	p4 は 表示する画像の X サイズ
	p5 は 表示する画像の Y サイズ

------------------------------------------------------------------------
	mem_picfree p1

	読み込んだ画像を開放します。
	使用が終わりましたら、必ず開放してください。
	
	p1 は mem_picloadで指定したIDを入れます。
	
------------------------------------------------------------------------

 ※ エラー値について

   stat =  2 : 画像ロードエラー? ( GDI+ API ) 
   stat = -1 : そのIDは利用されていません
   stat = -2 : そのIDは使用中の為、確保できません
   stat = -3 : ファイルサイズが異常です
   stat = -4 : 利用できないIDの範囲です

   ・0以外が返ってきたら基本的にエラーと考えてください

------------------------------------------------------------------------

*/

//以下サンプル

#if 0								//ここの値を1にするとサンプルが実行されます。

	//下準備
	fname = "testpic.png"				//ファイル名

	exist fname : ret = strsize			//ファイルサイズを取得(パックしても使える)
	sdim data, ret					//メモリを確保
	bload fname, data				//メモリにデータを読み込み(パックしても使える)


	mem_picinit						//初期化(初回1回のみ)

	mem_picload 0, data, ret			// メモリから読み込み(ID = 0)
	mem_picgetsize 0, x, y			// 画像のサイズを取得
	mem_picrectscreen 0, 0, 0, x, y		// HSPのウィンドウに 左上0,0 サイズx,yで転送
	width x, y						// picload ,0 風にw
	mem_picfree 0					// 使わなくなったら開放
	
#endif