comments to: http://www.powerbasic.com/support/pb...ad.php?t=12506
[this message has been edited by don schullian (edited september 29, 2005).]
Code:
this code imports images from files, resource or the clipboard using gdi+ functions and converts them to powerbasic's bmp graphics so they can be manipulated using pb's functions. if the incoming image needs to be stretched to fit a particular size then i've found that the gdi+ functions do a bit better job of it than graphic stretch. this code is quite simple and will, most likely need some boosting to get it into a real program but as needs and requirements change in unforeseeable ways i've not attempted to create the end-all function but just a simple skeleton as a starting point. special thanks go to the following (and some i've most likely missed) for their input: general gdi+ patrice terrier resource code ryan cross debugging aslan babakhanov using fgdip_2hbmp the filename parameter is used to determine where the image is to be loaded from. an incoming null value indicates that it is on the clip- board. a string starting with the pound sign chr$(35) indicates a resource label and any other string is a file path\name. if hbmp's incoming value is non-zero then it is assumed that you wish the function to load the image into the existing graphic. the function returns: zero if it has failed or powerbasic's bmp handle the value of hinst??? in loadimagefromresouce can be left as zero if the resource data is in the current program. that should do it! i've set some constants for the file name and resource label. use the bit of code directly following to create the test pbr file with your favorite picture. don schullian don (at) dasoftvss (dot)com ' '===================================================== '====== resource code ================================ '===================================================== ' #if 0 #include "resource.h" #define jpgtest 1001 jpgtest rcdata discardable "test.jpg" #endif ' '===================================================== '====== test code ==================================== '===================================================== ' #compile exe #compiler pbwin 8 #debug error on #dim all #resource "test.pbr" #include "win32api.inc" ' '===================================================== '====== declarations ================================= '===================================================== ' type gdiplusstartupinput gdiplusversion as dword '// must be 1 debugeventcallback as dword '// ignored on free builds suppressbackgroundthread as long '// false unless you're prepared to call the hook/unhook functions properly suppressexternalcodecs as long '// false unless you want gdi+ only to use its internal image codecs. end type type gdiplusstartupoutput notificationhook as dword notificationunhook as dword end type declare function gdiplusstartup lib "gdiplus.dll" alias "gdiplusstartup" (token???, inputbuf as gdiplusstartupinput, outputbuf as gdiplusstartupoutput) as long declare sub gdiplusshutdown lib "gdiplus.dll" alias "gdiplusshutdown" (byval token???) declare function gdipdeletegraphics lib "gdiplus.dll" alias "gdipdeletegraphics" (byval hgraphics???) as long declare function gdipcreatefromhdc lib "gdiplus.dll" alias "gdipcreatefromhdc" (byval hdc???, hgraphics???) as long declare function gdiploadimagefromfile lib "gdiplus.dll" alias "gdiploadimagefromfile" (byval flname$, lpimage???) as long declare function gdipcreatebitmapfromhbitmap lib "gdiplus.dll" alias "gdipcreatebitmapfromhbitmap" (byval hbm&,byval hpal&, nbitmap&) as long declare function gdipcreatebitmapfromstream lib "gdiplus.dll" alias "gdipcreatebitmapfromstream" (byval pstream???,m_pbitmap&) as long declare function createstreamonhglobal lib "ole32.dll" alias "createstreamonhglobal" (byval hglobal as dword, byval fdeleteonrelease as dword, pstm as dword) as long declare function gdipdisposeimage lib "gdiplus.dll" alias "gdipdisposeimage" (byval lpimage???) as long declare function gdipdrawimagerecti lib "gdiplus.dll" alias "gdipdrawimagerecti" (byval hgraphics???, byval nimage???, byval x&,byval y&, byval nwidth&, byval nheight&) as long declare function gdipgetimagewidth lib "gdiplus.dll" alias "gdipgetimagewidth" (byval lpimage???, nwidth???) as long declare function gdipgetimageheight lib "gdiplus.dll" alias "gdipgetimageheight" (byval lpimage???, nheight???) as long declare function gdipgetimagethumbnail lib "gdiplus.dll" alias "gdipgetimagethumbnail" (byval nimage&,byval thumbwidth&,byval thumbheight&, thumbnimage&, opt byval pcallback&, opt byval callbackdata&) as long ' '------------------------------------------- ' declare function pstreamrelease (punk???) as long declare function loadimagefromresource (byval resourcename$,opt byval hinst???) as dword declare function fgdip_2hbmp (byval filespec$,opt byval hbmp???) as dword ' '===================================================== '====== test code ==================================== '===================================================== ' $from_rc = "#1001" $from_file = "mugshot.jpg" $from_cboard = " %gdi_stretch = 1 $filespec = $from_file function winmain ( byval hinstance as dword, _ byval hprevinst as dword, _ byval lpszcmdline as asciiz ptr, _ byval ncmdshow as long ) as long dim gditoken as local dword dim startupinput as local gdiplusstartupinput dim hbmp as local dword dim bmpx as local single dim bmpy as local single dim hwnd as local dword dim xx as local single dim yy as local single startupinput.gdiplusversion = 1 if gdiplusstartup(gditoken, startupinput, byval %null) <> 0 then msgbox "no gdi+" exit function end if #if %gdi_stretch graphic bitmap new 300, 400 to hbmp #endif hbmp = fgdip_2hbmp($filespec,hbmp) if hbmp = 0 then msgbox "function failed" else graphic attach hbmp, 0 graphic get client to bmpx, bmpy graphic window ", 50, 50, 500, 500 to hwnd graphic attach hwnd, 0 graphic color %black, %yellow graphic clear if (bmpx > 500) or (bmpy > 500) then graphic stretch hbmp, 0, (0, 0)-(bmpx-1,bmpy-1) to (49,49)-(449,449) else xx = (500 - bmpx) \ 2 yy = (500 - bmpy) \ 2 graphic copy hbmp, 0 to (xx,yy) end if sleep 3000 graphic attach hbmp, 0 graphic bitmap end graphic attach hwnd, 0 graphic window end end if gdiplusshutdown gditoken end function ' '===================================================== '====== end test code ================================ '===================================================== ' function loadimagefromresource (byval resourcename as string, _ opt byval hinst as dword ) as dword dim hresource as local dword dim imagesize as local dword dim presourcedata as local dword dim m_hbuffer as local dword dim pbuffer as local dword dim pstream as local dword ptr dim m_pbitmap as local dword dim m_pbitmap_status as local long dim pname as local asciiz * %max_path pname = resourcename hresource = findresource(hinst, pname, byval %rt_rcdata) if hresource = 0 then exit function imagesize = sizeofresource(hinst, hresource) if imagesize = 0 then exit function presourcedata = lockresource(loadresource(hinst, hresource)) if presourcedata = 0 then exit function m_hbuffer = globalalloc(%gmem_moveable, imagesize) if m_hbuffer = 0 then exit function pbuffer = globallock(m_hbuffer) if pbuffer = 0 then goto exit_1 copymemory pbuffer, presourcedata, imagesize if createstreamonhglobal(m_hbuffer, %false, pstream) <> 0 then goto exit_2 m_pbitmap_status = gdipcreatebitmapfromstream(pstream, m_pbitmap) call dword @@pstream[2] using pstreamrelease(pstream) if (m_pbitmap <> 0) and _ (m_pbitmap_status = 0) then function = m_pbitmap end if exit_2: globalunlock m_hbuffer exit_1: globalfree m_hbuffer end function ' '------------------------------------------------------------------------------ ' function fgdip_2hbmp ( byval filespec as string, _ opt byval hbmp as dword ) as dword dim bx as local long dim by as local long dim hdc as local dword dim hgraphics as local dword dim himage as local dword dim ix as local long dim iy as local long dim htmp as local dword select case asc(filespec) case -1 : if openclipboard(htmp) = 0 then exit function htmp = getclipboarddata(%cf_bitmap) if htmp <> 0 then gdipcreatebitmapfromhbitmap htmp, byval %null, himage end if emptyclipboard closeclipboard if himage = 0 then exit function case 35 : himage = loadimagefromresource(filespec) if himage = 0 then exit function case else : filespec = ucode$(filespec) if gdiploadimagefromfile(filespec, himage) <> 0 then exit function end select gdipgetimagewidth himage, ix gdipgetimageheight himage, iy if hbmp = 0 then bx = ix by = iy graphic bitmap new bx, by to hbmp graphic attach hbmp, 0 gosub get_dc else graphic attach hbmp, 0 graphic get client to bx, by gosub get_dc if (bx <> ix) or _ (by <> iy) then gdipgetimagethumbnail himage, bx, by, htmp swap himage, htmp gdipdisposeimage htmp end if end if gdipdrawimagerecti hgraphics, himage, 0, 0, bx-1, by-1 gdipdeletegraphics hgraphics gdipdisposeimage himage function = hbmp exit function ' '------------------------------------- ' get_dc: graphic get dc to hdc gdipcreatefromhdc hdc, hgraphics if hgraphics <> 0 then return gdipdisposeimage himage graphic attach hbmp, 0 graphic bitmap end return end function
Comment