Heya, I couldn't find an easy way to save images in mojo2, so I've tweaked Fred's code from here to take a mojo2 canvas (instead of screen coordinates) and turn it into a bmp file:
Strict
'modified from Fred's code at monkey-x.com/Community/posts.php?topic=5528
Import mojo2
Import brl
Class BmpFile
Field Width:Int ' bmp image width
Field Height:Int ' bmp image height
Field Pixels:Int[1] ' array for screen Pixels
Field PixelDataBuffer:DataBuffer
Field FileSize:Int ' bmp file size
Field Buffer:DataBuffer ' bmp file PixelDataBuffer (header + Pixels)
Field PadLineWidth:Int ' bmp real line size
' default header for 24bpp image
Field Header:Int[] = [ $42,$4D,$D6,$83,$00,$00,$00,$00,$00,$00,$36,$00,$00,$00,$28,$00,$00,$00,$6C,$00,$00,$00,$68,$00,$00,
$00,$01,$00,$18,$00,$00,$00,$00,$00,$00,$00,$00,$00,$C3,$0E,$00,$00,$C3,$0E,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ]
Const FILE_SIZE := $2
Const IMAGE_WIDTH := $12
Const IMAGE_HEIGHT := $16
Const RAW_DATA_SIZE := $22
Method Create:Void(canvas:Canvas) ' Call within OnRender after drawing the image to grab
Width = canvas.Width
Height = canvas.Height
PadLineWidth = (((Width*3) + 3) / 4) * 4 'to get each line to end on a multiple of 4; req for .bmp format
'get the pixel data, convert it to an int array
PixelDataBuffer = New DataBuffer(Width*Height*4)
canvas.ReadPixels(0,0,Width,Height, PixelDataBuffer)
Pixels = Pixels.Resize(Width*Height*4)
PixelDataBuffer.PeekBytes(0, Pixels)
'set up the file (3 channels only; no transparency)
FileSize = Header.Length() + PadLineWidth * Height * 3
Buffer = New DataBuffer( FileSize )
'write the header information
local ptr:Int
for ptr = 0 until Header.Length
Buffer.PokeByte ptr, Header[ptr]
next
Buffer.PokeInt FILE_SIZE, FileSize
Buffer.PokeInt IMAGE_WIDTH, Width
Buffer.PokeInt IMAGE_HEIGHT, Height
Buffer.PokeInt RAW_DATA_SIZE, PadLineWidth * Height
'write to the databuffer that we'll eventually save as a .bmp
local i:Int = 0
local pix:= New Int[4]
for local ys:Int = Height-1 to 0 Step -1
ptr = (Height - ys - 1) * PadLineWidth + Header.Length
for local xs:Int = 0 until Width
For Local channel:Int = 0 to 2' R G B (omit A)
pix[channel] = Pixels[i+channel]
Next
Buffer.PokeByte ptr+0, pix[2] & $ff 'B
Buffer.PokeByte ptr+1, pix[1] & $ff 'G
Buffer.PokeByte ptr+2, pix[0] & $ff 'R
'update where we're writing to
ptr += 3
'update where we're reading from
i += 4
next
next
End
Method Save:Void( filename:String ) ' filename without .bmp
Local file:=FileStream.Open( "monkey://internal/"+filename+".bmp","w" )
If file
file.Write Buffer, 0, FileSize
file.Close
Endif
End
End
I also saw this thread that apparently is the key to saving pngs, but was too confused to really know where to start. Hopefully this'll be useful for people looking for a plug-and-play option.
(since it's a bmp, there's no transparency and it's uncompressed)
|