Fastest way to copy one image into another?

BlitzMax Forums/BlitzMax Programming/Fastest way to copy one image into another?

elcoo(Posted 2009) [#1]
Hi,
I wonder if there is a fast way to copy one image in to another in realtime? I tried using pixmap but it's waaayyy to slow. Are there any faster solutions?
The problem is that my image is pretty big (1600*2000 pixels) so even writing only one pixel needs pretty much time. But maybe i'm doing something wrong. My function looks like that:

Function SetImgColor(img,x,y,r,g,b,a=0)
Local pix:TPixmap = LockImage(img)
argb = ((a Shl 24) | (r Shl 16) | (g Shl 8) | (b Shl 0))*-1

WritePixel (pix,x,y,argb)
UnlockImage(img)

End Function


GfK(Posted 2009) [#2]
You don't want a 1600x1200 image. You should always use base 2 square images wherever possible.

A 1600x1200 one takes as much vram as a 2048x2048 image - roughly 16MB, or significantly more if you're using mipmapping. The reason its so slow after modifying even one pixel via a pixmap, is because the whole thing needs to be dumped to the graphics card again.

A faster way would be to load the image as a bunch of 128x128 (or anything smaller than 1600x1200) images. That way you only need to deal with one tiny section at a time.


plash(Posted 2009) [#3]
If you just need to simply recolor an image, you can use SetColor() (that is, if you have a graphical context going.


Jesse(Posted 2009) [#4]
also a way to do it faster is to access the pixels in the pixmap directly:
Function SetImgColor(img,x,y,r,g,b,a=0)
   local pixels:int ptr = int ptr(LockImage(img).pixels)
   pixels[y*img.width+x] = ((a Shl 24) | (r Shl 16) | (g Shl 8) | (b Shl 0))*-1 ' this writes the pixel to the pixmap
   UnlockImage(img)
End Function

if you need to set more than one pixel before drawing, don't go through the process of locking and unlocking the image for every pixel although the UnLockImage function has no use whatsoever.


elcoo(Posted 2009) [#5]
Ok, thanks for those tips! I now used several tiny squares and it works great!


plash(Posted 2009) [#6]
Note that you can also make a negative numerical value by just sticking a minus sign in front of it (instead of running a mul operator on the processor).

i.e.
pixels[y*img.width+x] = -((a Shl 24) | (r Shl 16) | (g Shl 8) | (b Shl 0))



Jesse(Posted 2009) [#7]
Looking at it logically, I don't believe that making the whole thing negative is the same as ORing it with a negative small value. Either way, I don't understand his use of it. That is why I left it alone.


ImaginaryHuman(Posted 2009) [#8]
You could draw to the backbuffer and use glCopyTexSubImage2d() in OpenGL.