Git Product home page Git Product logo

Comments (15)

oliver-moran avatar oliver-moran commented on July 19, 2024

I agree the constructor is awkward. I'd really prefer it if it could chain all the way. I'm just not sure what a promise would add.

For example, this is what we have at present:

var lenna = new Jimp("lenna.png", function (err, image) {
    this.resize(256, 256).quality(60).write("lenna-small.jpg");
});

With a promise would it look like:

var lenna = new Jimp("lenna.png").then(function (err, image) {
    this.resize(256, 256).quality(60).write("lenna-small.jpg");
});

There's probably not an awful lot of gain in that.

The library already supports chaining or callbacks. If promises were added across the board, I think we'd have to drop chaining (is that right?). I don't think that would be desirable.

A little known fact too is that in some circumstances the constructor is actually synchronous e.g. if creating a new image manually or if you are cloning an existing image.

I'm open to any practical suggestions though.

from jimp.

aeosynth avatar aeosynth commented on July 19, 2024

for me, the gain comes when mapping paths:

const promises = paths.map(path => new Jimp(path))
Promise.all(promises).then(jimps => ...)

although, this turns out to be impractical, since the bitmap is stored in memory

i'm currently using sharp, which has a nice api:

const lenna = sharp('lenna.png')
  .resize(256, 256)
  .quality(60)
  .toFile('lenna-small.jpg')

lenna.then(image => console.log('done'))

from jimp.

oliver-moran avatar oliver-moran commented on July 19, 2024

Agree. That's very nice.

The API I was originally targeting was something like this:

var lenna = new Jimp("lenna.png").resize(256, 256).quality(60).write("lenna-small.jpg");

That didn't seem possible because some parts of the constructor are asynchronous.

An issue I want to point out is that an approach like that might limit what can be done dynamically. For example, how could you do something like this using an API like that:

var lenna = new Jimp("lenna.png", function(err, image){
    // contain the image to a square and letterbox/pillarbox with the colour of the top-right pixel
    var max = (image.width > image.height) ? image.width : image.height;
    image.background(image.getPixelColor(0,0));
    image.contain(max , max).quality(60).write("lenna-square-letterbox.jpg");
}

A re-write of the constructor is probably a v0.3.0 release change. And I'm open to it. I added callbacks to give the same flexibility in pattern so if we can support promises too then great.

Let's think about what we could do to improve the constructor and see what we can do over the coming months for a v0.3.0 release.

from jimp.

dbkaplun avatar dbkaplun commented on July 19, 2024

+1 promises

from jimp.

aeosynth avatar aeosynth commented on July 19, 2024

with chainable constructors, your example would be

var lenna = new Jimp('lenna.png')
lenna.getImage((err, image) => ...)

making the constructor chainable is separate from supporting promises

from jimp.

iamstarkov avatar iamstarkov commented on July 19, 2024

its quite easy to use Bluebird’s Promise.promisifyAll to use Promises with any lib you want. just for me this issue can be safely closed

from jimp.

lukesneeringer avatar lukesneeringer commented on July 19, 2024

With a promise would it look like:

var lenna = new Jimp("lenna.png").then(function (err, image) {
    this.resize(256, 256).quality(60).write("lenna-small.jpg");
});

Actually, the syntax would be:

new Jimp('lenna.png').then(function(image) { 
  // note that "err" doesn't get passed; if the resolution runs, there was no error
}).catch(function(err) {
  // this is where the error function runs
});

The gains of using promises are:

(1) If you're using a library like bluebird, you can omit the .catch(err) boilerplate, because it will yell at you if an uncaught issue runs. That means a ton less of this in your code:

if (err) {
   // ...do something boring
}

It also means a lot easier debugging when you don't do that at all, which is incredibly common.

(2) Promises can be combined with things like Promise.all. So, instead of doing this:

funcRequiringCallback(function(err, data) {
  nextFuncRequiringCallback(function(err, data2) {
    yetAnotherFuncRequiringCallback(function(err, data3) {
      ...
    });
  });
};

You can do the much cleaner:

Promise.all([promise, promise2, promise3]).then(function(data) {
  ...
});

from jimp.

lukesneeringer avatar lukesneeringer commented on July 19, 2024

I'm also confused by the huge amount of example code that looks like

var image = new Jimp('lenna.png', function(err, image) {
  ...
});

Either image is saved as the variable result or used in the callback. It should not be both.
From experimenting, I've determined it's the latter. You should get rid of var image = in your documentation.

from jimp.

iamstarkov avatar iamstarkov commented on July 19, 2024

you described good part of promises but still you will got them for free with bluebird promisify

from jimp.

iamstarkov avatar iamstarkov commented on July 19, 2024

point about confusin var part is valid though

from jimp.

lukesneeringer avatar lukesneeringer commented on July 19, 2024

you described good part of promises but still you will got them for free with bluebird promisify

That's what I am doing in my code for now.
UPDATE: Actually, bluebird.promisifyAll doesn't know how to handle a constructor (new Jimp). So, I cannot do that.

It doesn't make the philosophical request less valid.
The post I was answering was where @oliver-moran said he did not see what promises would add. I am enumerating some of what they add.

from jimp.

oliver-moran avatar oliver-moran commented on July 19, 2024

OK. Promises will be in the next major release.

from jimp.

dbkaplun avatar dbkaplun commented on July 19, 2024

Nice one @oliver-moran!

from jimp.

oliver-moran avatar oliver-moran commented on July 19, 2024

OK. Promises are in. Everything works the same except you can now do:

Jimp.read("lenna.png").then(function (lenna) {
    lenna.resize(512, 512)           // resize
         .quality(60)                // set JPEG quality
         .greyscale()                // set greyscale
         .write("lena-small-bw.jpg") // save
}).catch(function (err) {
    console.error(err);
});

This is available on the main branch but is not published to NPM yet. If you could download it and see what you think, I'd appreciate that. All comments welcome.

from jimp.

oliver-moran avatar oliver-moran commented on July 19, 2024

I've released this now because of #58.

from jimp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.