Task: loading image files directly as buffers (or if you like - strings) and then converting into an image buffer used by PUT (x,y).
Troubles: the image libraries I found are converting 8 bpp bitmaps either into 32 bit or simply mix up the palette "automatically" - to the crappy VGA default.
Think of storing your bitmaps in a ZIP compressed file... - I don't want to make a temporary copy and then load the unpacked file.
- Where is the documentation of the image buffer format of FreeBASIC ? - Does it have a hidden part ?
- And what libraries do offer functions for image-data-decompression into a format, FreeBASIC can handle ?
Currently, I'm only interested in BMP and PNG, but GIF and JPEG hints won't disturb.
Loading image files... (BMP/PNG...)
Re: Loading image files... (BMP/PNG...)
I use the FBImage library: https://www.freebasic.net/forum/viewtopic.php?t=24105
Works great for at least .png (I've not used other formats), and loads directly into a Freebasic Image type.
There's a bit on "FB.IMAGE Data Type" which might answer your questions. Alternatively, just look directly at the fbgfx.bi; there are no "hidden parts" per-se other than the fact that you interact not with the type, but with the API through ImageCreate, ImageInfo, etc.
Works great for at least .png (I've not used other formats), and loads directly into a Freebasic Image type.
Image wiki is here: https://www.freebasic.net/wiki/TutFBgfxImgAndFontBuf- Where is the documentation of the image buffer format of FreeBASIC ? - Does it have a hidden part ?
There's a bit on "FB.IMAGE Data Type" which might answer your questions. Alternatively, just look directly at the fbgfx.bi; there are no "hidden parts" per-se other than the fact that you interact not with the type, but with the API through ImageCreate, ImageInfo, etc.
Hey if you're willing to manually fill in an FB.Image type yourself, then Freebasic can "handle" any format. The "handled" format is whatever you initialized the screen as (see also: https://freebasic.net/wiki/GfxInternalFormats). But as for image compression, I think the FBImage library also does saving to .png? I never needed it so I'm not sure.And what libraries do offer functions for image-data-decompression into a format, FreeBASIC can handle ?
Re: Loading image files... (BMP/PNG...)
Thank you very much. Unfortunately currently I don't have time to check it. That FB.Image IS the buffer format used by PUT resp. IMAGECREATE was a kind of mental brownout. At least it stands almost in the reference of IMAGECREATE, although not explained for dummies.
It seems that the FBIMage library can't load PNG files as 8 bpp buffer, at least you have to convert them back from 32 bpp. - Which is not impossible, but it costs me time again - and I still don't know, whether LoadRGBAFile() really loads a 8-bpp-PNG and just converts it into 32 bpp. Worst case could be that it can't load palettised PNG files.
It seems that the FBIMage library can't load PNG files as 8 bpp buffer, at least you have to convert them back from 32 bpp. - Which is not impossible, but it costs me time again - and I still don't know, whether LoadRGBAFile() really loads a 8-bpp-PNG and just converts it into 32 bpp. Worst case could be that it can't load palettised PNG files.
Re: Loading image files... (BMP/PNG...)
I've never used a palettised png, but here's the actual function I use when loading png images. I swap R/B due to satisfy the format my opengl shader uses. This loads images to a 32bits-per-pixel format (8 bits per color RGBA), then stores them in a direct 32 bit integer buffer, doing away with the FB.IMAGE type structure. Pallet conversion might be a bit more tricky I suppose.
Code provided as-is for reference and will not compile as it's missing context:
Code provided as-is for reference and will not compile as it's missing context:
Code: Select all
function LoadPNGFileRGBA(byval filename as const zstring ptr, RetVal as RGBATextureType ptr) as uinteger
dim loadedImage as any ptr
loadedImage = LoadRGBAFile(filename)
if loadedImage = 0 then
return 0
end if
dim as uinteger i,j
dim as integer w, h, bypp, pitch, size
dim as ubyte ptr pixelPtr, newPixels = 0
ImageInfo(loadedImage, w, h, bypp, pitch, pixelPtr, size)
if bypp <> 4 then
dprint("TextureHandling.bi: Error; loading image with pixel size ";bypp)
sleep
return 0
end if
newPixels = new ubyte[w*h*4]
dim as uinteger pitchW = pitch / 4
for i = 0 to h-1
for j = 0 to w-1
'Swap the R an B to make it properly adhere to OpenGL RGBA spec
newPixels[(i*(w*4)) + (j*4) + 0] = pixelPtr[(i*(pitchW*4)) + (j*4) + 2]
newPixels[(i*(w*4)) + (j*4) + 1] = pixelPtr[(i*(pitchW*4)) + (j*4) + 1]
newPixels[(i*(w*4)) + (j*4) + 2] = pixelPtr[(i*(pitchW*4)) + (j*4) + 0]
newPixels[(i*(w*4)) + (j*4) + 3] = pixelPtr[(i*(pitchW*4)) + (j*4) + 3]
next
next
ImageDestroy(loadedImage)
retVal->Width = w
retVal->Height = h
retVal->PixelPtr = cast(uinteger<32> ptr, newPixels)
return 1
end function
Re: Loading image files... (BMP/PNG...)
- I think you just have to add "SIZEOF(FB.IMAGE)" to the given pointer...
Conversion is easy because my RETROGRA library uses a palette that is RGB-based. Index 0-215 can be calculated with RGB steps of 0x33/51; R+G*6+B*36. You just can't use SHL/SHR/AND/OR for this though. If you'd have a higgledy-piggledy palette, it would be more difficult of course, you'd have to compare each pixel with all 256 colour entries and pick the nearest...
Conversion is easy because my RETROGRA library uses a palette that is RGB-based. Index 0-215 can be calculated with RGB steps of 0x33/51; R+G*6+B*36. You just can't use SHL/SHR/AND/OR for this though. If you'd have a higgledy-piggledy palette, it would be more difficult of course, you'd have to compare each pixel with all 256 colour entries and pick the nearest...
Re: Loading image files... (BMP/PNG...)
Windows.
For images 4 bytes or 1 byte per pixel
i.e.
screenres x,y,32
or
screenres x,y
to accept the picture/image
Will do .gif, jpg, jpeg, bmp, png, and maybe some others.
Also will load directly to fb screen if no image is used (like bload)
For images 4 bytes or 1 byte per pixel
i.e.
screenres x,y,32
or
screenres x,y
to accept the picture/image
Code: Select all
#if sizeof(integer)=8 '64 bits
#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 Long bpp
If i Then Imageinfo i,,,bpp Else Screeninfo,,,bpp
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)
If bpp=4 Then GDIPLUS.GdipBitmapLockBits(Img,Cast(Any Ptr,@R),GDIPLUS.ImageLockModeRead,PixelFormat32bppARGB,@Pdata)
If bpp=1 Then GDIPLUS.GdipBitmapLockBits(Img,Cast(Any Ptr,@R),GDIPLUS.ImageLockModeRead,PixelFormat8bppIndexed,@Pdata)
For y As Long = 0 To h-1
For x As Long = 0 To w-1
If bpp=4 Then Pset i,(x,y),Cast(Ulong Ptr,Pdata.Scan0)[y*w+x]
If bpp=1 Then Pset i,(x,y),Cast(Ubyte 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)
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
Dim As String picture=Curdir+"\bob.png" ' or whatever
If Fileexists(picture)=0 Then Print picture + " not found":Sleep:End
'get the desired image size and load the file to it
Dim As Single w,h
getsize(picture,w,h)
Screenres w,h,32
Dim As Any Ptr i=Imagecreate(w,h)
Pload(picture,i)
Put(0,0),i,Pset
Sleep
Imagedestroy i
Also will load directly to fb screen if no image is used (like bload)