News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Save Image As Bitmap

Started by kevin, January 11, 2006, 01:03:25 PM

Previous topic - Next topic

kevin

The function included here (and in few other threads) can be used to save images or the screen as a bitmap.

 To save the screen, use the image index 0..



PlayBASIC Code: [Select]
   Cls 0 
print "Saving... Please wait"
sync

sw=getscreenwidth()
sh=getscreenheight()

; Draw some Circles to the screen using alpha add mode
Print "Drawing some stuff to the screen"
Inkmode 1+64
For lp=0 to 100
Circlec Rnd(sw),rnd(sh),rnd(100),1,rndrgb()
next
inkmode 1


File$=Currentdir$() +"ScreenShot.Bmp"

Save_Image_As_BitMap(File$,0)


; Load the Screen shot in as an image
Loadimage File$,1


; delete the file
deleteFile File$


; draw the saved and re-loaded copy to the screen
drawimage 1,0,sh/2,0


Sync
waitkey




` *=---------------------------------------------------------------------=*
` >> Save Image As 32bit Bitmap <<
` *=---------------------------------------------------------------------=*
`
` This Function Saves an image buffer as a 32bit bitmap file.
`
` *=---------------------------------------------------------------------=*


Function Save_Image_As_BitMap(File$,ThisImage)

if ThisImage=0
Status=true
else
Status=GetIMageStatus(ThisIMage)
endif

if Status

BmpWidth=GetImageWIdth(ThisImage)
BmpHeight=GetImageHeight(ThisIMage)

if fileexist(file$)=1 then Deletefile file$

BmpWidth2=BmpWidth-1
BitDepth=32
Bytes=Bitdepth/8
ImageSize=BmpWidth*BmpHeight*Bytes
InfoHeaderSize=40
AbsFileSize=14+InfoHeaderSize+ImageSize

ThisFile=GetFreeFile()
WriteFile file$,ThisFile

Writeword ThisFile,19778
WriteInt ThisFile,AbsFileSize
WriteInt ThisFile,UseLess
WriteInt ThisFile,54 : Rem START of GFX data (offset)

WriteInt ThisFile,InfoHeaderSize
WriteInt ThisFile,BmpWidth
WriteInt ThisFile,BmpHeight
Writeword ThisFile,1 : Rem Planes
Writeword ThisFile,BitDepth
WriteInt ThisFile,0 : rem Compression (0=raw)

WriteInt ThisFile,ImageSize
WriteInt ThisFile,HPpM
WriteInt ThisFile,VPpM
WriteInt ThisFile,UsedColors
WriteInt ThisFile,ImportantColors

` -----------------
` Dump 32bit Bitmap
` -----------------
oldsurface=getsurface()
RenderToImage ThisIMage
lockBuffer
For ylp=BmpHeight-1 to 0 step -1
for xlp=0 to Bmpwidth2
WriteInt ThisFile,Point(xlp,ylp)
next Xlp
next Ylp
unlockbuffer
rendertoimage OldSurface
CloseFile ThisFile

endif

Endfunction






Ian Price

#1
That is a HUGE piece of code to do such a basic thing!

It's very good to have though :D

Is there any chance of a command that does the same thing in future PB updates? (like SaveBuffer(Buffer,"XX.BMP") in Blitz).
I came. I saw. I played some Nintendo.

kevin

Probably, but only as a module.

Digital Awakening

I suggest a save image command :)
Wisit my site at: DigitalAwakening.net

Ian Price

#4
QuoteI suggest a save image command :)

The SaveBuffer command I mentioned above does that - you can either save the image (ImageBuffer()) or the whole screen (FrontBuffer()). Both are VERY useful.

An external module will be fine, especially as that's the way you are taking PB anyway - I just hope it doesn't turn into BlitzMax...  ;)
I came. I saw. I played some Nintendo.

kevin

I guess that comparison is unavoidable.   All I can say at this time, is that we working towards a setup where the user won't actually have to do anything to activate/include standard PB or PBFX command set modules.   It' should all be transparent.   Well, apart from either opening new projects (obviously :) ) where you would select the type and perhaps importing an existing one.

Ian Price

As I've said before, a modular approach is a great idea - allows the user to (hopefully automatically) remove large chunks of code from the compiled game, reducing it's size, but retaining it's stability/functionality.

I mentioned BlitzMax as that was modular, but the language itself is a bit...

Will modular compilation be automatic (ie if your code doesn't include certain commands, then they won't be compiled/included)? BlitzMax makes you select the modules that you don't want at the start of your code - difficult if you don't know which modules you ARE actually using).

The more I use PlayBASIC, the more I like it, and look forward to each new update :)
I came. I saw. I played some Nintendo.

kevin

#7
QuoteWill modular compilation be automatic (ie if your code doesn't include certain commands, then they won't be compiled/included)?

 All dependencies are housed in your project file.  So when you open new project in the new IDE.  You'll be presented with a selection of project types to choose from.  Ie.  PB or  PBFX.     Mind you there won't be much of selection for a while.   But at least the door is open.    For example, the ColdSteel developers could create a CS3D project default, rather than an include library.   Then users would simply install the CS materials and their off.  

 Loading current projects should be plug and play.   They'll automatically default to the PB module set.  Not sure  how easy swapping project formats will be.   But i'm hoping it'll be as easy as selecting 'convert project'.  

 One difficultly is things like cutting and pasting code from the forums into the IDE.  There's really no way that i can think of to determine which set of modules the code should use in this case.  Given that function names+parameters for prolly 90% of PB and PBFX will be the same.  

 However if you downloaded a project  you'll just load & run it. The only time this might be drama would be if it uses modules you don't have installed   I.e  Obviously if you downloaded a ColdSteel project you'll need to have that installed before it'll run.

Well, i'd better shut up :).  Don't really want to release the cat out of the bag just yet.   But I hope you get the idea.

Ian Price

I came. I saw. I played some Nintendo.

thaaks

I tried to use this function to create in-game screenshots from Astrobreak.
But all I got was the starfield background (drawn with DotC).
I didn't see a single sprite in the screenshot.
Is there something not working as expected or did I make a mistake?

Cheers,
Tommy

Ian Price

I think it depends on where the blitter is at the time of running the screenshot function - you need to ensure that it runs it AFTER the sync command.

I wrote a similar function in Blitz, which needs to be run after the FLIP command.

Alternatively, try putting a SYNC at the start of the screenshot function.

I may be completely wrong though, but it solved the problem in Blitz.
I came. I saw. I played some Nintendo.

thaaks

Good idea!
But it didn't help  :(

Kevin? Any idea?

Ian Price

#12
Are you sure it's running AFTER everything else has been drawn? Make it the last possible function just before the main function loops (but before CLS).
I came. I saw. I played some Nintendo.

thaaks

Stupid me!
You are absolutely right, Ian.
I just called it at the wrong place - namely in my PlayerUpdate() routine. But that one is called nearly at the beginning of the main loop...

Now it's working as expected  :rolleyes:

...need to test more before asking stupid forum questions...


Thanks,
Tommy