LOAD PNG TO IMAGE

New to FreeBASIC? Post your questions here.
Forgotten Coder
Posts: 6
Joined: Jan 12, 2019 12:23

LOAD PNG TO IMAGE

Post by Forgotten Coder »

Hello everybody

I am the Forgotten Coder and after searching this forum i couldn't find a simple sub that loads a png file into an image. Maybe i didn't search enough ...

So my challenge to this community of coders is to "Make a sub with the name LoadPNG to load PNG files to an image".
Made some starting code for this challenge to avoid people saying "We do the work and this guy does nothing" LOL.

I think this challenge will benefit everyone is this community. I am doing this not just for me. :)

Code: Select all

'*******************************************************
'filename: pngtoimage.bas
'
'function: LoadPNG
'
'Description: loads a png image to an freebasic image
'
'Syntax: LoadPNG(file,imageid)
'
'parameters:
'
'> file: filepath to png image
'> imageid: id of image
'*******************************************************

#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
Using FB '' Screen mode flags are in the FB namespace in lang FB
#endif

'************************************************
' HIDE CONSOLE
'************************************************
#If Defined(__FB_WIN32__)
declare function hideConsoleWindow alias "FreeConsole"() as long
hideConsoleWindow
#EndIf

declare sub loadPNG(file as string, image as any pointer)

windowtitle("LoadPNG")
screen 20,32 '1024x768

dim image as any pointer
dim file as string
dim as integer x, y

x=100
y=100

image=imagecreate(32,32, rgba(255,255,255,255)) 'white background
file="test.png" 'make 32 x 32 png file called test.png

do
  loadPNG(file,image)
  put (x,y), image 'position image in screen

  sleep
  imagedestroy image
loop until inkey=chr$(27)


sub loadPNG(file as string,image as any pointer)
'in here i am lost
'in here i am lost
'in here i am lost
'in here i am lost
end sub



leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: LOAD PNG TO IMAGE

Post by leopardpm »

check the library FBimage for various graphical filetype loadings...
once you have the FBimage library loaded, then it is a simple statement

Code: Select all

dim shared as any ptr campfire
campfire = imagecreate(32,32) 'or whatever
campfire = LoadRGBAFile("data/graphics/Campfire.png")
it is an unfortunate circumstance that FB only directly supports BMP file loading.... argh...

also, in your code, you probably don't want to put the loading of an image (from disk), in your display loop! nor the 'destroyimage' there either!

Code: Select all

do
  loadPNG(file,image)
  put (x,y), image 'position image in screen

  sleep
  imagedestroy image
loop until inkey=chr$(27)
Forgotten Coder
Posts: 6
Joined: Jan 12, 2019 12:23

Re: LOAD PNG TO IMAGE

Post by Forgotten Coder »

Hi Leopard

Thanks for tips and advices. I will look for that fbimage library and test it.

For now i am enjoying this idea of making this sub. Testing first bytes of a png file 32x32 made with gimp application. A black limited square painted in yellow. I know this will get more complicated from now on. Need help. Maybe we can make this sub/function for the next version of FB. LOL Just kiding i am not the boss of anything in here. :)

Code: Select all

'*******************************************************
'filename: pngtoimage.bas
'
'function: LoadPNG
'
'Description: loads a png image to an freebasic image
'
'Syntax: LoadPNG(file,imageid)
'
'parameters:
'
'> file: filepath to png image
'> imageid: id of image
'*******************************************************

#include "fbgfx.bi"
#if __FB_LANG__ = "fb"
Using FB '' Screen mode flags are in the FB namespace in lang FB
#endif

'************************************************
' HIDE CONSOLE
'************************************************
#If Defined(__FB_WIN32__)
declare function hideConsoleWindow alias "FreeConsole"() as long
hideConsoleWindow
#EndIf

declare sub loadPNG(file as string, image as any pointer)

windowtitle("LoadPNG")
screen 20,32 '1024x768

dim image as any pointer
dim file as string
dim as integer x, y
dim f as integer

f=freefile

x=400
y=400

image=imagecreate(32,32, rgba(255,255,255,255)) 'white background
file="test.png" 'make 32 x 32 png file called test.png

cls
loadPNG(file,image)
do
  put (x,y), image 'position image in screen
  sleep
loop until inkey=chr$(27)
imagedestroy image
end 'program

sub loadPNG(file as string,image as any pointer)
    
   'type pngheader
   '  byte1 as ubyte '89 - ???
   '  byte2 as ubyte '50 - letter P
   '  byte3 as ubyte '4e - letter N
   '  byte4 as ubyte '47 - letter G
   '  byte5 as ubyte '0d - DOS Carrige Return
   '  byte6 as ubyte '0a - DOS Linefeed
   '  byte7 as ubyte '1a - DOS end of file
   '  byte8 as ubyte '0a - Unix LineFeed
   'end type
      
   dim chunklen as ubyte   
   dim chunkletter as ubyte   
   dim chunkwidth as ubyte
   dim chunkheight as ubyte
   dim chunkbitdepth as ubyte
   dim chunkcolortype as ubyte
   dim chunkcompressionmethod as ubyte
   dim chunkfiltermethod as ubyte
   dim chunkinterlacemethod as ubyte
   
   'dim header as pngheader
   dim ub as ubyte
   dim passed as integer
  
   If Open(file For Binary Access Read As #1) = 0 Then
     print "open file with sucess"
     
     passed=0
     
     '**********************************
     'read png header and validate it
     '**********************************
     get #1, ,ub
     if hex(ub)="89" then passed=passed+1
     get #1, ,ub
     if hex(ub)="50" then passed=passed+1
     get #1, ,ub
     if hex(ub)="4E" then passed=passed+1
     get #1, ,ub
     if hex(ub)="47" then passed=passed+1
     get #1, ,ub
     if hex(ub)="D" then passed=passed+1
     get #1, ,ub
     if hex(ub)="A" then passed=passed+1
     get #1, ,ub
     if hex(ub)="1A" then passed=passed+1
     get #1, ,ub
     if hex(ub)="A" then passed=passed+1
          
     if passed=8 then
       print "it's a png file"
     else
       print "this is not a png file"  
     endif    
     print
     
     get #1, ,chunklen
     get #1, ,chunklen
     get #1, ,chunklen
     get #1, ,chunklen
     print ("chunksize="+str(chunklen)+" bytes") '13 bytes
     
     'read the 4 letters of first critical chunk named IHDR
     get #1, ,chunkletter
     print ("chunknameletter1="+chr$(chunkletter)+" 1 byte")
     get #1, ,chunkletter
     print ("chunknameletter2="+chr$(chunkletter)+" 1 byte")
     get #1, ,chunkletter
     print ("chunknameletter3="+chr$(chunkletter)+" 1 byte")
     get #1, ,chunkletter
     print ("chunknameletter4="+chr$(chunkletter)+" 1 byte")
     
     'read 13 bytes of chunk info
     print 
     print "read 13 bytes of chunk info"
     print
     
     'first chunk width
     get #1, ,chunkwidth
     get #1, ,chunkwidth
     get #1, ,chunkwidth
     get #1, ,chunkwidth
     print ("chunkwidth="+str(chunkwidth)+" pixels (4 bytes)")
     
     'first chunk height
     get #1, ,chunkheight
     get #1, ,chunkheight
     get #1, ,chunkheight
     get #1, ,chunkheight
     print ("chunkheight="+str(chunkheight)+" pixels (4 bytes)")
     
     get #1, ,chunkbitdepth
     print ("chunkbitdepth="+str(chunkbitdepth)+" (1 byte)")
     get #1, ,chunkcolortype
     print ("chunkcolortype="+str(chunkcolortype)+" (1 byte)")
     get #1, ,chunkcompressionmethod
     print ("chunkcompressionmethod="+str(chunkcompressionmethod)+" (1 byte)")
     get #1, ,chunkfiltermethod
     print ("chunkfiltermethod="+str(chunkfiltermethod)+" (1 byte)")
     get #1, ,chunkinterlacemethod
     print ("chunkinterlacemethod="+str(chunkinterlacemethod)+" (1 byte)")
     close #1
   else
     print "error opening file"  
   end if
  
end sub




leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: LOAD PNG TO IMAGE

Post by leopardpm »

i think creating the entire PNG loading routine would be pretty involved, especially considering the various(?) possible compression techniques... though you have a good start on the header already... still would suggest just using the library... MUCH simpler and you can continue on with your program instead of being sidetracked (something that occurs to me all the time...)
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: LOAD PNG TO IMAGE

Post by lizard »

Forgotten Coder wrote:Hello everybody

I am the Forgotten Coder and after searching this forum i couldn't find a simple sub that loads a png file into an image. Maybe i didn't search enough ...
Welcome, here you will be remembered. We are fiddling around a lot with libs from the C world. There we find everything which is not in FB itself, including all the file loaders.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: LOAD PNG TO IMAGE

Post by dodicat »

If you use windows, then keeping things as simple as possible, please try this.
Does other formats also.

Code: Select all

#if sizeof(integer)=8
#include "windows.bi"
#endif
#Include  "win/gdiplus.bi"

#include "file.bi"
'An idea from UEZ in another thread.
Function Pload(Picture as String,byref i as any ptr=0) as long
   Dim As uinteger TMP 
   GDIPLUS.GdiplusStartup(@TMP,@type<GDIPLUS.GDIPLUSSTARTUPINPUT>(1),0)
   Dim as any Ptr Img
   if GDIPLUS.GdipLoadImageFromFile(Picture,@Img)>0 then return 0
   Dim As Single w,h
   GDIPLUS.GdipGetImageDimension(Img,@w,@h)
   if w*h=0 then return 0
   Dim As GDIPLUS.BitmapData Pdata
   Dim As Rect R=Type(0,0,w-1,h-1)
   GDIPLUS.GdipBitmapLockBits(Img,Cast(Any Ptr,@R),GDIPLUS.ImageLockModeRead,PixelFormat32bppARGB,@Pdata)
   For y as long = 0 To h-1
      For x as long = 0 To w-1 
           pset i,(x,y),Cast(ulong Ptr,Pdata.Scan0)[y*w+x]
      Next
   Next
return w*h
End Function

sub getsize(picture as string,byref w as single,byref h as single) 'unused
    Dim As uinteger TMP 
   GDIPLUS.GdiplusStartup(@TMP,@type<GDIPLUS.GDIPLUSSTARTUPINPUT>(1),0)
   Dim as any Ptr Img
   if GDIPLUS.GdipLoadImageFromFile(Picture,@Img)>0 then exit sub
   GDIPLUS.GdipGetImageDimension(Img,@w,@h)
end sub

screen 20,32
'get the desired image size and load the file to it
dim as single w,h

dim as string picture="bob.png"
if fileexists(picture)=0 then print picture + "  not found"
getsize(picture,w,h)

dim as any ptr i=imagecreate(w,h)
Pload(picture,i)
put(0,0),i,pset
sleep
imagedestroy i

 
 
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: LOAD PNG TO IMAGE

Post by leopardpm »

dodicat wrote:If you use windows, then keeping things as simple as possible, please try this.
Does other formats also.
What?! So... if someone is using Windows, then this simple routine will work instead of having to force folks to use a library (FBimage)? which makes the program complete unto itself... never seen this in all my years here... will give it a go... does it matter 32 or 64 bit?

What other formats will it load?
Last edited by leopardpm on Jan 12, 2019 23:04, edited 1 time in total.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: LOAD PNG TO IMAGE

Post by dodicat »

32 or 64.
give it a shot.
leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: LOAD PNG TO IMAGE

Post by leopardpm »

of course, alot of folks here seem to use linux in some form, and some mac users too I think.... so being windows only is kinda limiting, for the source.... still, nice to know
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: LOAD PNG TO IMAGE

Post by dodicat »

leopardpm
Posts: 1795
Joined: Feb 28, 2009 20:58

Re: LOAD PNG TO IMAGE

Post by leopardpm »

dodicat wrote:Here is Bob at Drumbreddan Bay.
http://www.mediafire.com/file/xz4zp3i38 ... b.zip/file
your dog? cute!
lizard
Posts: 440
Joined: Oct 17, 2017 11:35
Location: Germany

Re: LOAD PNG TO IMAGE

Post by lizard »

Nice dog!

Most of the time i am using libs ,ike cairo, fltk-c or fbimage where .png is included, so no need to care for this. And they all are platform independent. Maybe you decide one day to switch to linux or mac like i did. When only surfing or programming with geany i simply not notice a real difference in the view, because they are the same programs. But Linux Mint boots up much faster and it is a pain to hear windows rattling all the time on the HD. So why programming windows only if we can do it platform independent with the same effort?
Tourist Trap
Posts: 2958
Joined: Jun 02, 2015 16:24

Re: LOAD PNG TO IMAGE

Post by Tourist Trap »

I forgot to download Imagemagick on my win10, so I'll have to. Anyway, in my opinion the easiest way is to shellexecute a Imagemagick command to do the conversion to a BMP. There is some test to do maybe because I don't know what bmps know about transparency. However all the code for conversion is already done and in any platform it will/should work.
https://imagemagick.org/script/convert.php
Use the convert program to convert between image formats as well as resize an image, blur, crop, despeckle, dither, draw on, flip, join, re-sample, and much more. SeeCommand Line Processing for advice on how to structure your convert command...
Forgotten Coder
Posts: 6
Joined: Jan 12, 2019 12:23

Re: LOAD PNG TO IMAGE

Post by Forgotten Coder »

Hi everyone

Last night i was "crusing" the freebasic directory c:\freebasic\inc and found out this 5 files.
png.bi
png12.bi
png14.bi
png15.bi
png16.bi


Complete mistery to me ... Does anyone knows how to use them ... Maybe they got a loading function in them ... Really don't know how to use them.

PS: Thank you all for your tips and code.
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: LOAD PNG TO IMAGE

Post by badidea »

I assume that there are multiple, incompatible versions of libpng

In .../examples/files/libpng there is png.bas
This uses png.bi [ #include once "png.bi" ]

If I run this it get:
* ... incompatible linbpng version ... (in the grahics window)
* libpng warning: Application was compiled with png.h from libpng-1.6.18
* libpng warning: Application is running with png.c from libpng-1.2.54

So, I could add #define __LIBPNG_VERSION 12 in png.bas, before #include once "png.bi
Or change this is png.bi
Or just replace #include once "png.bi" with #include once "png12.bi"

And it works here. You do need however "libz" (or zlib) and 'libpng", else you get:
ld: cannot find -lpng
ld: cannot find -lz
Compilation failed.

Proof that it can work:
Image
Post Reply