Search code examples
javascripthtmllinuxframebuffer

Convert framebuffer dump to image(bmp, png, etc.)


I have a server where I am dumping the framebuffer data using cat /dev/fb0 > fbdump.raw and sending this file's contents to web client to display as a screenshot. Tried quite a few links before posting the question, but none helped in rendering an image on HTML/JS client side.

Is there any processing required on client side or is there any readymade API available for this in JavaScript? Any suggestions are appreciated. Thanks in advance.

Referred Links:


Solution

  • You can put ImageData (raw RGBA image data stored in a Uint8ClampedArray) on a canvas.

    You have to convert the framebuffer dump (BGRA) to RGBA by swapping red and blue. Setting the alpha to 255 (opaque) is nececary as well, because the linux framebuffer doesn't use the alpha channel so it is usually 0 (transparent).

    fetch("fbdump.raw") // load the dump
    .then(response => response.arrayBuffer()) // convert the response to a ArraBuffer
    .then(array_buffer => {
        let canvas = document.querySelector("canvas") // get the canvas
        let ctx = canvas.getContext("2d") // get the context
        let raw_data = new Uint8ClampedArray(array_buffer) // use the ArrayBuffer as a Uint8ClampedArray for easier acces and the constructor of ImageData needs a Uint8ClampedArray
        for (let i = 0; i < raw_data.length; i += 4) {
            // convert the BGRA dump to RGBA
            let b = raw_data[i + 0]
            raw_data[i + 0] = raw_data[i + 2]
            raw_data[i + 2] = b
            raw_data[i + 3] = 255 // set alpha to 255 to make it non transparent (the alpha ist set to 0 and is unused in the linux framebuffer)
        }
    
        let image_data = new ImageData(raw_data, 1920, 1080) // create a new ImageData object with a resolution of 1920x1080
    
        // set the canvas resolution to 1920x1080
        canvas.width = 1920
        canvas.height = 1080
    
        ctx.putImageData(image_data, 0, 0) // puts the image on the canvas, starting at (0,0)
    })
    

    This code assumes the framebuffer has a resolution of 1920x1080 and the BGRA pixel format.