Chopping up pixmaps and making images

BlitzMax Forums/BlitzMax Programming/Chopping up pixmaps and making images

Hi,

I plan to do the following but I need your help please:

1) load in a pixmap with alpha channel, create another pixmap and draw the loaded pixmap back to it, with rotation and scaling (pre-rendering some frames), then finally save the new pixmap as a png with alpha.

2) load in a pixmap and create an image. I then copy bits from the pixmap to the image to create a single image with lots of different bits of the pixmap in it (think single surface)... then free the pixmap.

Are these two things achievable? I really hope they are. If you can help then I would really appreciate it. I just don't know how to do these actions. I am not looking for entire source, just magic commands and techniques I can work with.

1) Not sure how to handle that.

2) Use pixmap.Window( cx, cy, cw, ch ).Paste( destPixmap, x, y )

Thanks noel.

Regarding point 2, I want to copy lots of bits of a pixmap to the same image:TImage, not another pixmap.

Well Pixmap.Window creates a new pixmap, so you could just do pixmap.Window( x, y, w, h ).Paste( pixmap, x, y ).

You could lock an image and then use .paste to put pieces onto it, but there's really not need to use images if you do it all in pixmaps.

thanks so I use lockimage, then mypixmap.paste to copy it into the image?

I apologise but I need it explained to me because at the moment I'm very confused.

Check-out the codes by Grisu here
this part paste a smaller pixmap onto a larger one
If FileType("iconstrip.png")=0 Then   
 Global Fullpixmap:TPixmap=CreatePixmap(((MAXFOLGEN)*ICONSIZE),ICONSIZE,PF_BGR888,1) 
 Local tmppixmap:TPixmap 

 For Local i:Int=0 To MAXFOLGEN-1  
    tmppixmap=LoadPixmap("0.jpg")  '96x96 Pixel icon!
    fullpixmap.paste(ResizePixmap(tmppixmap,ICONSIZE-2,ICONSIZE-2),1+i*ICONSIZE,1)
 Next 
 SavePixmapPNG(fullpixmap, "iconstrip.png",9 )
EndIf 


Do all your pixmap manipulation then
image:TImage=loadimage(pixmap).
However, getting a scaled rotated image/pixmap into another image is either slow (draw it to backbuffer then grabpixmap) or complicated by creating a 'rendertarget'.
You can't do this with native Bmax.

I only need to get a rotated pixmap into another pixmap, this is absolutely essential... is it missing?

I do need to copy 'normal' pixmaps into a larger image though if at all possible.

> I only need to get a rotated pixmap into another pixmap, this is absolutely essential... is it missing?


Yes, the only way to do it is to draw the rotated image on the screen and then grab that onto the pixmap - and then go on with drawing the screen you want the use to see before doing the flip. (unless something new has been added in the last couple releases)

..or use Indiepath's Render2Texture.
What's annoying for me is Imagebuffers were superb in B2D/B3D (even by BRL's admission) but overlooked in BMax. It's been proved possible but not in native Bmax because, I think, it uses texture management (at least for DX).
Oh, and I can't seem to get pixmap.paste to work the way it used to either.
<edit> Ooops, can get it to work but it ignores masking.
That's why I went through this convoluted scenario...
Graphics 640,480
image1:TImage=LoadImage("max.png")
image2:TImage=LoadImage("light.png")
While Not KeyHit(key_escape)
	Cls
	If MouseHit 
		argb:Int=intcolor(image2.mask_r,image2.mask_g,image2.mask_b)
		image1:TImage=drawbuffer(image1,image2,0,0,argb)
	EndIf
	DrawImage image1,0,0
	Flip
Wend
WaitKey()
Function drawbuffer:TImage(imagea:TImage,imageb:TImage,x:Int,y:Int,argb:Int)
  If x + ImageWidth(imageb) > ImageWidth(imagea) Or y + ImageHeight(imageb) > ImageHeight(imagea) RuntimeError("Imagea to big to fit in imageb")
'  start_func=MilliSecs()
  mypixmap2:TPixmap=LockImage(imageb)
  UnlockImage(imageb)
  mypixmap1:TPixmap=LockImage(imagea)
  Local mypixelptr2:Int Ptr = Int Ptr(mypixmap2.pixelptr(0,0))
  Local mypixelptr2backup:Int Ptr = mypixelptr2
  Local mypixelptr1:Int Ptr = Int Ptr(mypixmap1.pixelptr(x,y))
  Local mypixelptr1backup:Int Ptr = mypixelptr1
  For my_x=0 To ((mypixmap2.width)*(mypixmap2.height))
     If mypixelptr2[0] <> argb 
         If mypixelptr2[0] <> 0 mypixelptr1[0]=mypixelptr2[0]
 '             If mypixelptr2[0] <> 16777215 mypixelptr1[0]=mypixelptr2[0]
    EndIf
     mypixelptr1:+1
     mypixelptr2:+1
     If mypixelptr2 = mypixelptr2backup+(mypixmap2.pitch Shr 2)
         mypixelptr1 = mypixelptr1backup+(mypixmap1.pitch Shr 2)
         mypixelptr1backup=mypixelptr1
         mypixelptr2backup=mypixelptr2
     EndIf
  Next
  Return LoadImage(mypixmap1)
'  end_func=MilliSecs()
End Function
Function IntColor(R,G,B,A=255)
'returns argb value from red, green, blue.
     Return A Shl 24 | R Shl 16 | G Shl 8 | B Shl 0
End Function


hardware isn't available on this machine - thanks :)

So I need a genuine software solution...

That code can be used with just pixmaps. Sub the loadimage with loadpixmap and use them directly rather than lockimage pixmaps.