Saving large base64 images with node.js

    Javascriptresolved

    John J.A. Jannone's icon
    John J.A. Jannone's icon
    John J.A. Jannone
    Mar 01 2023 | 4:37 pm
    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
    maxpat 71.01 KB
    Thanks for any advice!

    • John J.A. Jannone's icon
      John J.A. Jannone's icon
      John J.A. Jannone
      Mar 01 2023 | 8:12 pm
      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");
      
      });
      
      Share
    • Rob Ramirez's icon
      Rob Ramirez's icon
      Rob Ramirez
      Mar 02 2023 | 4:36 pm
      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
      John J.A. Jannone's icon
      John J.A. Jannone
      Mar 03 2023 | 4:06 am
      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)
                      })
      
      })