Saving large base64 images with node.js

John J.A. Jannone's icon

Hey all,
I'm successfully downloading base64 PNG files using an http request, but I can only save them up to about 120x120 pixels. I'm guessing I'm hitting a size limit somewhere in node.js...

const path = require('path');
const Max = require('max-api');
const fs = require('fs');
    
Max.addHandler("png", (data) => {
    var buf = new Buffer(data, 'base64');
    fs.writeFile('image_temp.png', buf,  function(err, result) {
         if(err) post('error', err); });
});
test.maxpat
Max Patch

Thanks for any advice!

John J.A. Jannone's icon

Tried this - did not work - maybe I'm importing node:buffer incorrectly? I get "Buffer.alloc is not a function."

const Buffer = require('node:buffer');
const path = require('path');
const Max = require('max-api');
const fs = require('fs');
    
Max.addHandler("png", (data) => {
    var buf = Buffer.alloc(262144, 'base64');
    data.copy(buf, data);
    fs.writeFile('image_temp.png', buf,  function(err, result) {
         if(err) post('error', err); });

Max.outlet("done");

});
Rob Ramirez's icon

hey John, this n4m code last ran in 2021, but it did write base64 images (coming in from Runway-ML) to disk as png images at 1024x1024. I couldn't tell you everything this code is doing (especially that string replace on the first line), but here it is in case it's useful:

//////////////////// Save base64 image into local disk //////////////////////////////////
function writeBinaryImagesToDisk() {
    // m.post(base64String) //base64 image
    let base64Data = base64String.replace(/^data:image\/\w+;base64,/, '')
        // m.post(base64Data) // remove first part of the string
    let binaryImage = Buffer.from(base64Data, 'base64')
        // m.post(binaryImage) 

    // lodash library enumerate the generated file names
    let imgNumber = _.padStart(count, 4, '0')

    // combine folder and image number
    let imgTitle = `${imgFolder}/image_${imgNumber}.png`

    // write a file with the image name in the folder, where the script is located
    // throws a warning:ERR_INVALID_CALLBACK. Ignore it...
    fs.writeFile(`${imgTitle}`, binaryImage, err => {
        if (err) m.post(err)
        //m.post(`The file ${imgTitle} has been saved!`)
        m.outlet("write", `${imgTitle}`)
    })
    count++
    //if (count <= framePerSecond * videoLength) {
        //setTimeout(generateImage(), 100) // delay time
    //}
}

... 
The above function called here
...

    const data = {
            z: a, //assign the generated latent space vector a to the Z space
            truncation: truncation, //variation in image generations - higher is more random, lower is more similar
        }
        // POST = send data (latent vector)
        // GET = request data (resulting image)
    axios
        .post(postURL, data)
        .then(() => {
            axios
                .get(getURL)
                .then((response) => {
                    //assign the base64 encoded image as string to the base64String variable
                    base64String = response.data.image

                    // call the function to save the base64 image in the png format
                    writeBinaryImagesToDisk()
                })
                .catch((error) => {
                    m.post(error)
                })
        })
        // .catch((error) => {
        //     m.post(error)
        // })
John J.A. Jannone's icon

Yes thanks so much Rob! Had to mess with it a bit, but getting all image sizes now!

const path = require('path');
const Max = require('max-api');
const fs = require('fs');
const axios = require('axios');

//////////////////// Save base64 image into local disk //////////////////////////////////
function writeBinaryImagesToDisk(INPUT) {
    

    let IMG = Buffer.from(INPUT[0], 'base64')
 //       Max.post(IMG) 

 
    fs.writeFile(`temp.png`, IMG, err => {
        if (err) Max.post(err)

        Max.outlet("write", "saved")
    })

}



Max.addHandler("bang", () => {


    const PAYLD = {
        "prompt" : "two cats",
        "steps" : 5,
        "width" : 1024,
        "height" : 512
    };

    axios
        .post("http://127.0.0.1:7861/sdapi/v1/txt2img", PAYLD)

                .then((RESPONSE) => {
                    //assign the base64 encoded image as string to the base64String variable
                    BASE64 = RESPONSE.data.images

         //  Max.outlet("raw", (BASE64))
                    // call the function to save the base64 image in the png format

                    writeBinaryImagesToDisk(BASE64)
                })
                .catch((error) => {
                    Max.post(error)
                })

})