2

Take two.

In my nodejs application I need to extract a rectangular part of a JPEG image. I have the coordinates (x, y, width, height), I just need to crop.

There are many libraries that can do this (sharp, jimp, lwip, etc) but they all follow the decompress-modify-recompress pattern.

Since this is a server application and I'll probably need to do this for multiple pictures per second, I'd like to make it as performant as possible.

Luckily, I don't need the crop to be precise. It's no problem if the result is a few pixels larger. Thus I could use lossless JPEG extraction1 on properly aligned coordinates. It would both save CPU cycles, memory and avoid any potential quality loss.

I know this can be done because there are already tools out there that do it - just none that I could find were written in Javascript. I would also like to avoid CLI tools because I suspect that the overhead of writing to disk/calling tool/collecting the result would be far greater than just doing the recompression dance in memory with the available libraries (however if you have an argument for this approach, I'll accept that as an answer as well).

So - how do I losslessly crop a JPEG image (on properly aligned coordinates), in Javascript (node.js, server side)? The output is, of course, another JPEG image.

1 Note that "lossless" in this case doesn't mean "lossless JPEG". It means "lossless crop", where a part of a JPEG is extracted without decompressing/recompressing it. It's one of the few lossless operations that are possible on a JPEG.

Vilx-
  • 104,512
  • 87
  • 279
  • 422
  • 1
    Important reading about lossless JPEG: https://stackoverflow.com/questions/7982409/is-jpeg-lossless-when-quality-is-set-to-100 suggestion: use png. – Steven Stark Apr 04 '19 at 23:21
  • @StevenStark - Nonononono. That's not it. I don't mean "lossless JPEG". I mean "lossless crop". As in, I crop a part of the original JPEG without decompressing/recompressing. It's still as lossy as the original JPEG is - just without extra losses because of the cropping. There are a few operations that can be done losslessly on a JPEG - see here: https://en.wikipedia.org/wiki/JPEG#Lossless_editing – Vilx- Apr 04 '19 at 23:24
  • Have you tried submitting a feature request to `sharp` or asking them directly if it can be done?. Or maybe submit a pull request. – Marcos Casagrande Apr 04 '19 at 23:34
  • @MarcosCasagrande - Well... I'll try. Although it won't help me right now. Also `sharp` uses a native library, and already ran afoul of that when trying to use `bcrypt`. Worked on my machine, failed on the server. Thus I prefer pure-javascript solutions, even if they are somewhat slower. Then again, this could be one place to bite the bullet and accept the exception. I'll think about it. – Vilx- Apr 04 '19 at 23:43
  • 3
    [Mozjpeg.js](https://www.npmjs.com/package/js-mozjpeg) supports `jpegtran`. –  Apr 05 '19 at 00:41
  • @RemisaYousefvand That's... Huh... Interesting. I'll check it out, thanks! – Vilx- Apr 05 '19 at 05:03

0 Answers0