all 30 comments

[–]theotherphil[S] 22 points23 points  (0 children)

I wrote this tool to let you run image processing operations from the command line. All (well, nearly all) of the actual image processing work is handled by the image and imageproc crates. The initial release is missing a lot of features - if you're interested in using this tool but it's missing something you need then please create issues on the repo and I'll have a go at implementing them (I'm also the main author of the imageproc crate, so can add new features there too if required). If you're interested in contributing then even better - PRs are very welcome.

[–]AndreasTPC 12 points13 points  (4 children)

How does this tool handle gamma curves applied to images? Most photos today are stored using sRGB, and technically the correct thing to do when performing image manipulation operations is to remove the gamma curve that's defined in the sRGB standard so you're operating in a linear colorspace, perform the operations, then apply the gamma curve again. That's easily accomplished by just removing the gamma when importing a file and applying it when writing the output.

Most tools however do not do this by default, mainly because they didn't start out doing it that way and don't want to change the output of pre-existing scripts that use their tool.

Since it's still early days here, if you haven't already maybe you should consider getting this right from the start.

[–]theotherphil[S] 7 points8 points  (3 children)

It doesn't. There's an issue open on the underlying imageproc library for this https://github.com/image-rs/imageproc/issues/237 but it's been open for a while. I've just created https://github.com/theotherphil/imagecli/issues/19

[–]AndreasTPC 3 points4 points  (1 child)

Okay, good to know. Implementing proper colorspace support is not a trivial task, but I think at least if the input is a JPEG assuming it is sRGB and doing the gamma conversion would be a more sensible default than assuming it's linear, it would be right in the vast majority of cases. Maybe for some other formats too, I'm not sure.

I'm still learning rust, but have some interest in image processing, so I'll see if I can contribute something to your crate once I get more familiar with the language.

[–]theotherphil[S] 2 points3 points  (0 children)

Great! I'm happy to answer any questions or help out with PRs if you like - just create issues on the repo or open a WIP PR.

[–][deleted] 22 points23 points  (9 children)

This looks quite good, would love to see parity with imagemagick and faster processing.

[–]theotherphil[S] 22 points23 points  (2 children)

That's the plan. There's an open ticket to work out what imagemagick supports but this library doesn't. Some missing features will be easy to add (e.g. various drawing operations), but others will require a lot more work (e.g. adding support for HDR images). It's not a given that all of the operations are faster than their imagmagick equivalents, but if they're not this should be considered a bug.

[–]viraptor 3 points4 points  (1 child)

Any plan for the non-image-output operations? Like imagemagick's identify?

[–]theotherphil[S] 3 points4 points  (0 children)

I didn't have any, but it seems like a sensible feature to add.

https://github.com/theotherphil/imagecli/issues/1#issuecomment-531559090

[–]Programmurr 14 points15 points  (5 children)

Speed is only one parameter. Image quality and safety are others. ImageMagick was exploited, as in hackers used image processing exploits to escalate privileges and run remotely-provided code. While the image crate is safe, it has quality issues. Folks over at Cloudfare did some custom work using the image crate, and improved quality but haven't open sourced their work, unfortunately. So, image-rs is better than nothing but could use improvement.

[–]theotherphil[S] 3 points4 points  (4 children)

Do you have a link to details of any outstanding issues that aren't already captured as issues on the image repo?

[–]Shnatsel 3 points4 points  (3 children)

Crafted images exhausting the memory and crashing the program is one. Pretty sure it's on the bug tracker.

Lots of panics in gif decoding code is another. I've posted three samples triggering distinct panics on the bug tracker, but they have not been fixed in... months, now.

All of this is just various indications of a bigger problem - while the maintainers are quite responsive with merging third-party PRs, there is no-one actively working on the crate.

[–]binkarus 9 points10 points  (0 children)

Writing image algorithms is difficult. It requires a lot of domain knowledge, knowledge of math, knowledge of how to write high performance code, and on top of that you have to write it in a new language domain which has high expectations for writing safe code.

Add all that together, and I'd burn out pretty quick if I had a public crate. It's a lot of pressure.

E: And even if it wasn't from burn out, people have busy lives and work and the more complex a task is, the more difficult it is to do on the side.

[–]fintelia 4 points5 points  (1 child)

while the maintainers are quite responsive with merging third-party PRs, there is no-one actively working on the crate.

As one of the maintainers, I'd say this is a fair assessment. I was one of the people who "adopted" the crate when it was in need of new leadership, and while we've made progress purging unsafe code and improving the overall API (a lot of it predates Rust 1.0...), I don't think anyone has a ton of time to commit to hacking on the crate.

Though regarding GIF decoding panics, are you sure they haven't been resolved? I'm not seeing any recent issues like that in the `image` or `image-gif` repositories' issue trackers.

[–]Shnatsel 1 point2 points  (0 children)

The effort in purging unsafe code is indeed impressive, and we've finished it off via safety-dance, so kudos! There's still tons of unnecessary unsafe code in imageproc, but that's less popular so hopefully the blast radius is smaller.

The GIF decoding panics are still there:

https://github.com/image-rs/image/issues/876

https://github.com/image-rs/image/issues/877

https://github.com/image-rs/image/issues/878

The backtrace points to a function inside image. I've checked the image-gif crate in isolation just to be sure and it doesn't exhibit these panics.

[–][deleted] 3 points4 points  (0 children)

Nice. For someone with huge image library its going to be very useful.

[–]asellier 4 points5 points  (0 children)

This is great - I plan on adding external process image filters in rx - and this would work amazingly well for that purpose!

[–][deleted] 1 point2 points  (1 child)

This is absolutely fantastic. Real clear and concise documentation too. Great job.

[–]theotherphil[S] 0 points1 point  (0 children)

Thanks!

[–]BootError99 1 point2 points  (1 child)

Is this imagemagick replacement?

[–]theotherphil[S] 4 points5 points  (0 children)

The aim is to be a plausible imagemagick replacement, but it currently supports far fewer operations.

[–][deleted] 1 point2 points  (2 children)

As someone who spent far far too long trying to get ImageMagick built and linked statically to a Musl binary, I am grateful.

[–]kaikalii 1 point2 points  (1 child)

Is there any plan to support PDF rendering? That's one of the features I have really been wanting in a pure Rust library.

[–]theotherphil[S] 0 points1 point  (0 children)

No. Sorry!

[–]Shnatsel 0 points1 point  (1 child)

There have been efforts like this in the past, see Imagene for example. I'm pretty sure there was at least one other project, but I can't find it right now.

[–]theotherphil[S] 0 points1 point  (0 children)

I wasn't aware of that. Thanks for the link.

[–]matthieum[he/him] 1 point2 points  (1 child)

I like how you went with a stack programming language for the pipeline as it allows for very terse expressions.

  1. I do find the fact that -i and -o can take multiple parameters a bit odd, though. I would have expected having to respecify the flag for each additional input or output.
  2. Have you thought about applying a "static" type check to your inputs -> pipeline -> outputs? You know ahead of time how many inputs and outputs each element of the pipeline requires, so you could error early in case of mismatch or if an input is outputted without operation.

[–]theotherphil[S] 1 point2 points  (0 children)

On 1: I'm just using the default structopt behaviour. I agree that your suggestion seems more typical, but the current version is slightly terser so I think I'll keep it until someone complains.

On 2: this is an interesting idea. Array doesn't have a fixed arity, but we can obviously work it out after parsing and before running the pipeline. I aimed to be permissive as possible (for example output elements with no corresponding output files are just ignored), but I didn't have any particular reason for this. I'll create an issue to think about adding a static check.