Jimp: Jimp Streams

Created on 16 Jun 2016  Â·  15Comments  Â·  Source: oliver-moran/jimp

The existing resize methods provides option either to write to file or gives a buffer.
Is there a way where resize can return a readable stream , in this way we can skip the overhead of converting buffer to stream

plugin-candidate

All 15 comments

Makes sense to have this. If you write a method, I'll pull it in. Otherwise, I'll add it to the backlog.

+1

+1

+1

Seems like after a year there are no plans to return streams instead of buffers?

+1

+1

This is most useful way that i found, to work with streams:

import * as jimp from 'jimp';
import * as fs from 'fs';
import {Duplex} from 'stream';

import {promisify} from 'util';

const read = promisify(fs.readFile);
const write = fs.createWriteStream(__dirname + '/photo2.jpg');

read(__dirname + '/photo.png')
    .then((result) => {
        return jimp.read(result);
    })
    .then((img) => {
        const r = img.resize(100, 100);
        const b = promisify(r.getBuffer.bind(r));
        return b(jimp.MIME_PNG);
    })
    .then((buff) => {
        const stream = new Duplex();
        stream.push(buff);
        stream.push(null);
        return stream;
    })
    .then((stream) => {
        return stream.pipe(write);
    })
    .then((data) => {
        console.log(data);
    })
    .catch((err) => {
        console.log('error', err);
    });

This part converts buffer to stream:

.then((buff) => {
        const stream = new Duplex();
        stream.push(buff);
        stream.push(null);
        return stream;
    })

@thread So you guys want a function writeStream which returns the encoded data as a stream? No matter what we have to make the data into a buffer before you get the data back. We have to encode the bitmap data into the desired format. So I'm not sure you can really skip the conversion to a buffer.

Ideas?

@gabriellesc @niftylettuce @rbarriuso @meszaros-lajos-gyorgy @Romesz @dannyk08 @Enitoni @0xff00ff What would you wan the API to look like?

is there a way to use Express to retrieve an image using JIMP ?

`generateArt = (text = "COMMUNITY") => {
Jimp.read("./bgImage.jpg")
.print(
civilFont,
209,
0,
{
text: theText,
alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT,
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
},
834,
1920
)
.getBuffer(Jimp.MIME_JPEG, buff => {
return buff;
});
};

app.get("/art/:words", function(req, res) {
res.set("Content-Type", "image/jpeg");
var buffer = generateArt(req.params.words);
console.log(buffer);
res.status(200).send(new Buffer(buffer));
});`

I get errors:

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type undefined
at Function.from (buffer.js:208:11)
at new Buffer (buffer.js:183:17)

@hipstersmoothie I created https://lipo.io and use that instead of jimp and sharp by itself

@niftylettuce that's cool that you made that but it doesn't really answer my question. I've never used streams and am not sure what the API might look like if i were to implement it. What would you want that API to look like?

@omarojo The following code works

Problems I found with your code:

  1. Jimp.read returns a promise so you have to await it's result and chain later
  2. getBuffer takes a node style callback so the first param will be an error or null. the second param is where the buffer actually lies
const Jimp = require('jimp');

test();

async function test(text = 'COMMUNITY') {
  const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
  const image = await Jimp.read('./exampleImages/anime.png');

  image
    .print(
      font,
      209,
      0,
      {
        text,
        alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT,
        alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
      },
      834,
      1920
    )
    .getBuffer(Jimp.MIME_JPEG, (err, buff) => {
      console.log('GOT BUFFER:', buff);
      return buff;
    });
}

you could simplify it further too:

const Jimp = require('jimp');

test().then(console.log); // the then will get the buffer

async function test(text = 'COMMUNITY') {
  const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
  const image = await Jimp.read('./exampleImages/anime.png');

  image.print(
    font,
    209,
    0,
    {
      text,
      alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT,
      alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
    },
    834,
    1920
  );

  return image.getBufferAsync(Jimp.MIME_JPEG);
}

As for why the following code doesn't work:

  1. your version of generateArt returns nothings so var buffer never gets a value. This causes your error. If you use my function.1 I return nothing and new Buffer will not work. In function.2 i retrun a promise so you ould hav
app.get('/art/:words', function(req, res) {
  res.set('Content-Type', 'image/jpeg');
  var buffer = generateArt(req.params.words);
  console.log(buffer);
  res.status(200).send(new Buffer(buffer));
});

Full Working Code (I have not ran the express part):

async function generateArt(text = 'COMMUNITY') {
  const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
  const image = await Jimp.read('./exampleImages/anime.png');

  image.print(
    font,
    209,
    0,
    {
      text,
      alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT,
      alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
    },
    834,
    1920
  );

  return image.getBufferAsync(Jimp.MIME_JPEG);
}

app.get("/art/:words", async (req, res) => {
  res.set("Content-Type", "image/jpeg");
  const buffer = await generateArt(req.params.words);
  res.status(200).send(new Buffer(buffer));
});

Got it Thanks !
On Sep 13, 2018, 13:58 -0700, Andrew Lisowski notifications@github.com, wrote:

@omarojo The following code works
Problems I found with your code:

  1. Jimp.read returns a promise so you have to await it's results and chain later
  2. getBuffer takes a node style callback so the first param will be an error or null. the second param is where the buffer actually lies

const Jimp = require('jimp');

test();

async function test(text = 'COMMUNITY') {
const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
const image = await Jimp.read('./exampleImages/anime.png');

image
.print(
font,
209,
0,
{
text,
alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT,
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
},
834,
1920
)
.getBuffer(Jimp.MIME_JPEG, (err, buff) => {
console.log('here', buff);
return buff;
});
}
you could simplify it further too:
const Jimp = require('jimp');

test().then(console.log); // the then will get the buffer

async function test(text = 'COMMUNITY') {
const font = await Jimp.loadFont(Jimp.FONT_SANS_32_WHITE);
const image = await Jimp.read('./exampleImages/anime.png');

image.print(
font,
209,
0,
{
text,
alignmentX: Jimp.HORIZONTAL_ALIGN_LEFT,
alignmentY: Jimp.VERTICAL_ALIGN_MIDDLE
},
834,
1920
);

return image.getBufferAsync(Jimp.MIME_JPEG);
}
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub, or mute the thread.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

haydenbleasel picture haydenbleasel  Â·  6Comments

tutyamxx picture tutyamxx  Â·  4Comments

dtrofimov picture dtrofimov  Â·  5Comments

PainKKKiller picture PainKKKiller  Â·  5Comments

SamuelZhaoY picture SamuelZhaoY  Â·  3Comments