• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Saving image to .png/.bmp

Pierrou

Well-known member
Joined
Jul 6, 2017
Messages
237
Hi,
Back in the Monkey-X days user Fred (Frédérick Raynal) wrote a module to save images to .bmp files (Mojo1). Does anyone still have this piece of code somewhere? (or something equivalent?)
Thanks!
 
@JaviCervera 's framework Vortex includes a FontTool which can save to PNG files at least. If no one is coming up with a monkey module, maybe try to study the source and adapt things you need.
 
Thanks Mike! Looks quite complicated (C++ and stuff) to me :oops::oops::)
I could do without saving pics but being able to get screenshots would be quite useful to me.
 
Hey @Pierrou! I modified it before the forums went down to work with mojo2, I hope it might be helpful for you?

Code:
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

Usage:

In my user input:
Code:
if KeyHit(KEY_F8) Then takeScreenshot = True

In my main draw method (using a mojo2 canvas):
Code:
If takeScreenshot
    screenshot = New mojo2.Image(screenwid, screenhet, .5, .5)
    canvas.SetRenderTarget(screenshot)
EndIf



'< draw everything you want to be in the screenshot >


If screenshot <> Null
    local screenshotcanvas:= New Canvas()
    screenshotcanvas.Clear(0.0, 0.0, 0.0)
    screenshotcanvas.DrawImage(screenshot, screenwid/2, screenhet/2)
              
    'save the screenshot
    Local bmp:= New BmpFile()
    bmp.Create(screenshotcanvas)
    bmp.Save("testscreenshot")
      
    canvas.SetRenderTarget(Null)

    screenshot = Null
    takeScreenshot = False
EndIf
 
Another option for PNG is in the Regal module, but I ran into the same problem that it was too complicated for me to figure out.
 
Thanks a lot Wick! Tied to Mojo1/IgnitionX for my current project but very useful thanks. I forgot about the Regal module, will try to use it.
 
Back
Top Bottom