No CopyImage

BlitzMax Forums/BlitzMax Beginners Area/No CopyImage

Grey Alien(Posted 2007) [#1]
Hmm, so BMax has no CopyImage command. I haven't needed it until just now. I did a search and found a thread that said draw it to the backbuffer and then grab it but this might be a bit slow for on-the-fly copies due to you having to call CLS first and then do the grab image.

Is there a way to perhaps access the underlying TPixmap and copy that? Thanks. I really just want to go like this:

myimage:TImage = CopyImage(anotherimage)

or maybe

myimage:TImage = anotherimage.Copy()

or even

myimage:TImage = TImage.CreateFromCopy(anotherimage)

you get the idea...


Suco-X(Posted 2007) [#2]
Hi
You could use somthing like this:

function CopyImage:Timage(Image:TImage)
return LoadImage(LockImage(Image)))
end function


Grey Alien(Posted 2007) [#3]
aha that's pretty cool, so it's not really loading it from disk, it's loading it from an existing copy in memory. Thanks!


ImaginaryHuman(Posted 2007) [#4]
It's transferring it from video ram over the graphics bus to main memory, turning it into a pixmap, and then turning it back from a pixmap to a image, sending it all back over the graphics bus into video memory. That's not exactly a fast alternative and if anything is surely slower than:

DrawImage
GrabImage
DrawRect (over the affected area only)

That keeps it all in video ram and will be much faster than involving pixmaps.


Grey Alien(Posted 2007) [#5]
really?


grable(Posted 2007) [#6]
I dont think so. As GrabImage() calls GrabPixmap().
in D3D7Max2D it creates a surface in ram to copy to, then uses BitBlt(), and in GLMax2D it uses glReadPixels.

Then again, i dont know that much about d3d7 or gl so i could be wrong ;)


tonyg(Posted 2007) [#7]
Not sure that's true as GrabImage does a GrabPixmap.
Can you call image.setpixmap directly?


FlameDuck(Posted 2007) [#8]
That's not exactly a fast alternative
Compared to what? A pixmap is a trivial amount of data, that even a PCI bus should have no trouble transferring in a sensible time, never mind an AGP or PCI-Ex16 bus.


BlackSp1der(Posted 2007) [#9]
Why don't you create a new image and copy all image data? :S

Graphics 800,600,0

Local image:TImage=CreateImage(800,600)
Local a:TImage=CopyImage(image)
DebugStop

Function CopyImage:TImage(image:TImage)
	Local newimage:TImage=CreateImage(image.width,image.height,image.frames.Length,image.flags)
	newimage.handle_x=image.handle_x
	newimage.handle_y=image.handle_y
	newimage.mask_r=image.mask_r
	newimage.mask_g=image.mask_g
	newimage.mask_b=image.mask_b

	For Local frame:Int=0 Until image.Frames.Length
		Local pixmap:TPixmap=LockImage(image,frame)
		'pixmap copy
		newimage.SetPixmap(frame,pixmap.Copy())
		'pixmap clon
		'newimage.pixmaps[frame]=image.pixmaps[frame]
		'newimage.frames[frame]=image.frames[frame]
		'newimage.seqs[frame]=image.seqs[frame]
		UnlockImage(image,frame)
	Next

	Return newimage
EndFunction



ImaginaryHuman(Posted 2007) [#10]
Sounds silly. Create a dummy new Image and do like glCopyTexSubImage2D() to grab the backbuffer into it. There is no reason why pixmaps ever need be involved.


Yan(Posted 2007) [#11]
Images can only be copied on the second Sunday of every other month...Except on a leap year.


H&K(Posted 2007) [#12]
Am I missing something here. Dont you do most of the work of changing an image/pixmap when it is a pixmap. So why would you want to copy an image? It the same Image as it was the last time you changed the pixmap. Isnt it?

If so, either just make two copies of the image when its a pixmap, or just have two pointers to the same image. Or when you change the image. (ie when you have had to make it a pixmap) copy it then


Grey Alien(Posted 2007) [#13]
Hmm this grows more interesting. Thanks Blackspider. So how fast is that?

H&K and others: OK here's why I want to do it. I have a whole load of objects pointing to the same image (loaded in earlier) which has a top left origin (for good reasons). Then sometimes I want to transfer the origin to the centre (midhandle) on one object only and scale it. Of course, as the objects all point at the same image, if I midhandle that, they ALL midhandle, so no good.


ImaginaryHuman(Posted 2007) [#14]
So you need basically a static image like a static bank - a TImage structure that can tie in with a texture in video ram but with different handle settings, like how static banks and pixmap windows work.

You sort of need to be able to make a new TImage instance without it generating a whole new image, and then copy over the image reference from the original, so two TImage structures use the same texture data.

Just copy and modify the Create() function from BRL.Max2d.Image.bmx file:

	Function DuplicateImage:TImage(OldImage:TImage,handx#,handy#)
		Local t:TImage=New TImage
		t.width=OldImage.width
		t.height=OldImage.height
		t.flags=OldImage.flags
		t.mask_r=OldImage.mask_r
		t.mask_g=OldImage.mask_g
		t.mask_b=OldImage.mask_b
		t.pixmaps=OldImage.pixmaps
		t.frames=OldImage.frames
		t.seqs=OldImage.seqs
             t.handle_x=handx
             t.handle_y=handy
		Return t
	End Function


You don't need to be copying any actual pixel data at all. If all you need is a unique set of handles then you can just duplicate the data structure and not the image itself.


Yan(Posted 2007) [#15]
Or just set and reset the image's handles as and when you need to?


Grey Alien(Posted 2007) [#16]
AngelDaniel: Interesting aproach! good thinking.

Yan: Uh yeah, why didn't I think of that. Just need a flag and then a special draw command.