Graphics objects as image buffers...

BlitzMax Forums/BlitzMax Programming/Graphics objects as image buffers...

jondecker76(Posted 2010) [#1]
I'm currently building an application which "builds" composite images in various resolutions from many source images.
At first i tried drawing the final output image on a pixmap, but was missing scaling, rotation, alpha, etc...

Then I had the idea to use "Graphics Objects" as image buffers. So now in my program, I manually create the image buffer I need before calling Grapics()
Global bufPrintout:TGraphics = CreateGraphics(800,1200,0,60,0)
Global bufBackBuffer:TGraphics = Graphics(SETTINGS.GetInt(opt_app_width),SETTINGS.GetInt(opt_app_height),0,60,0)



then later in the program, where I actually render my output image:
...
...
		Local imgPrintoutBackground:TImage=LoadImage("./resources/1x4template_landscape.jpg")
		'Use our previously created "buffer"
		SetGraphics(bufPrintout)
		'draw the background first...
		DrawImage(imgPrintoutBackground,0,0)
		'then draw all of the thumbnails over the background
		Local count:Int=0
		For tn = EachIn TPic.list
			
			'for each thumbnail, draw it!
			DrawImage(LoadImage(tn.pixmap_thumb),10+count*390,10)
			count=count+1
		Next
		'now lets grab our "render"
		Local pixTest:TPixmap=GrabPixmap(0,0,1200,800)
		'and save the resulting image
		If Not ReadDir(SETTINGS.GetString(opt_savepath_printouts))
			CreateDir(SETTINGS.GetString(opt_savepath_printouts))
		EndIf		
		SavePixmapJPeg(pixTest,SETTINGS.GetString(opt_savepath_printouts)+"/"+MakeFilename(),100)
		
		'Return to normal rendering
		SetGraphics(bufBackBuffer)
		
		 sequence.donext()


Ok, the good news is - this actually works, and in the end I get a file saved exactly as I want it.
The bad news is, that the extra CreateGraphics() call creates another window! (the window is just black)
This would be perfect if it didn't create the extra window!

Does anyone know how I could do this without the bad side-effect of the extra window appearing? (MaxGUI for example, the Canvas gadget obviously creates a drawing area without an extra window, so there must be a way to do it!)

thanks!


jondecker76(Posted 2010) [#2]
Here is a screenshot to better illustrate what I am talking about:



(sorry for the huge size, but I run 3 monitors on my linux box, so the image is 3840x1024 pixels.. How can I post this as a direct link instead of an inline image? You may have to copy the link location to see it directly on photobucket...)

Anyways, to explain the screenshot.. The application running and the BMX IDE are on the right. Right in the center of the screen you can see the extra window (which is transparent to what is beneath it). Also, if you look at the task bar at the bottom, you will see "Blitzmax Application" twice :( )


Jaydubeww(Posted 2010) [#3]
Possibly use endgraphics after you get the image you want? This probably wont work considering I dont know when/where/why the extra screen is being created. Also note when you call endgraphics, all previously used variable handles will be lost. At least this is how it worked in b3d.


Leon Drake(Posted 2010) [#4]
i remember what i used to do when i needed something render on a graphics object like that is if you have maxgui create a hidden window then just make a graphics canvas on it.


jondecker76(Posted 2010) [#5]
I was considering using MaxGUI and creating a canvas, but I was trying to avoid bloating the program if possible. Hopefully mark sees this post as I'm sure he would be the one that has a solution. And if its not possible, we really need a buffer type that lets you draw on it without creating an extra window! (I can't simply draw on the backbuffer and grab it, as my output resolution is different than my screen resolution)


Leon Drake(Posted 2010) [#6]
if your just drawing images why not just use pixmaps like this?


		Local imgPrintoutBackground:TImage=LoadImage("./resources/1x4template_landscape.jpg")
		'Use our previously created "buffer"
		'SetGraphics(bufPrintout)<---- screw that use pixmaps!
                local buffprint:Tpixmap = CreatePixmap(800,1200,PF_RGBA8888)
		'draw the background first...
		local pixbg:TPixmap = LockImage(imgPrintoutBackground)
                unlockImage(imgPrintoutBackground)
                buffprint.Paste(pixbg,0,0)
		'then draw all of the thumbnails over the background
		Local count:Int=0
		For tn = EachIn TPic.list
			
			'for each thumbnail, draw it!
			 buffprint.Paste(tn.pixmap_thumb,10+count*390,10)
			count=count+1
		Next
		'now lets grab our "render"
		'Local pixTest:TPixmap=GrabPixmap(0,0,1200,800)
		'and save the resulting image
		If Not ReadDir(SETTINGS.GetString(opt_savepath_printouts))
			CreateDir(SETTINGS.GetString(opt_savepath_printouts))
		EndIf		
		SavePixmapJPeg(buffprint,SETTINGS.GetString(opt_savepath_printouts)+"/"+MakeFilename(),100)
		
		'Return to normal rendering
		'SetGraphics(bufBackBuffer)
		
		 sequence.donext()






jondecker76(Posted 2010) [#7]
The reason I changed from using PixMaps is because there are no scale, rotation or alpha options (all of which I will need). I thought it would be nice to use TImages instead, as I won't have to code all of this manually like I would if I were to continue with pixmaps!


jondecker76(Posted 2010) [#8]
maybe BRL could be nice enough to make another flag to be used with the Graphics() or CreateGraphics() commands which would supress the creation of a new window? I.e. GRAPHICS_NOWINDOW...


Leon Drake(Posted 2010) [#9]
you can get the hwnd of it and make it hidden