Coder Social home page Coder Social logo

foresterre / sic Goto Github PK

View Code? Open in Web Editor NEW
158.0 7.0 6.0 3.92 MB

๐Ÿฆœ Accessible image processing and conversion from the terminal. Front-end for image-rs/image.

License: Apache License 2.0

Rust 98.26% Handlebars 0.55% Makefile 0.19% Shell 0.14% PowerShell 0.58% Just 0.29%
rust cli image-processing image-converter terminal-app convert-images sic image-manipulation command-line blur

sic's Introduction

The sic project logo

sic image cli

ci Crates.io version shield Docs Crates.io license shield

Convert images and perform image operations from the command-line.

sic (sic image cli) is a front-end for the image crate. Aside from image operations supplied by the image crate, a few additional helpful operations such as diff, are included. Operations provided by the imageproc crate can be enabled by compiling with the imageproc-ops feature. We intend to provide more extensive support for imageproc operations in a future release. sic supports operations on both static and animated images.

Installation

Install with cargo:

  • run cargo install sic

Pre build binaries

Build from source

  • Setup rust and cargo (for example using rustup)
  • Clone this repo: git clone https://github.com/foresterre/sic.git && cd sic
  • Build a release: cargo build --release

sic is usually build against the latest stable Rust version, but may also work with older versions.

Using a package manager

Homebrew

๐Ÿบ Homebrew on MacOS:

brew tap tgotwig/sic
brew install tgotwig/sic/sic

๐Ÿบ Homebrew on Linux:

brew tap tgotwig/linux-sic
brew install tgotwig/linux-sic/sic

emerge

gentoo linux via GURU overlay:

emerge -av media-gfx/sic

Usage

Convert images

Convert an image from one format to another, for example from PNG to JPG.

  • Command: sic --input <input> --output <output>
  • Shorthand: sic -i <input> -o <output>
  • Example: sic -i input.png -o output.jpg

If you want to explicitly set the image output format, you may do so by providing the --output-format <format> argument. Otherwise, sic will attempt to infer the format from the output file extension.

--help can be used to view a complete list of supported image output formats. Included are:

  • AVIF, BMP, OpenExr, Farbfeld, GIF, ICO, JPEG, PNG, PNM (PAM, PBM, PGM and PPM), QOI TGA, TIFF and WebP.

The JPEG quality can optionally be set with --jpeg-encoding-quality <value>. The value should be in the range 1-100 (with default 80). Files which are formatted with a PNM format (with one subtype of PBM, PGM and PPM) use binary encoding (PNM P4, P5 and P6 respectively) by default. To use ascii encoding, you can provide the following flag: --pnm-encoding-ascii.

Convert or apply operations on a set of images

For the use case where you have a directory containing several (hundreds of) images which you like to convert to different format, or on which you perhaps want to apply certain image operations, sic provides built-in glob pattern matching. This mode can be used by providing the --glob-input and --glob-output options instead of --input and --output respectively.

Examples:

  • To convert a directory of images from PNG to JPG, you can run sic with the following arguments:
    • sic --glob-input "*.png" --glob-output output_dir --output-format jpg"
  • To convert all images with the jpg, jpeg and png extensions to BMP:
    • sic --glob-input "*.{jpg, jpeg, png}" --glob-output output_dir --output-format bmp
  • To emboss all images in a folder (assuming it contains only supported image files and no folders):
    • sic --glob-input "*" --glob-output embossed_output --filter3x3 -1 -1 0 -1 1 1 0 1 1

A few things worth noticing: 1) We use quotation marks (") around the input argument, so our shell won't expand the glob pattern to a list of files. 2) When using glob mode, our output (--glob-output) should be a folder instead of a file. 3) We need to explicitly state the output format with --output-format, unless we work with a known extension we want to keep.

Output images are placed in the output folder using the directory structure mirrored from the first common directory of all input files. If output directories do not exist, they will be created.


Image operations

In sic, you can manipulate images using image operations. Image operations can be used directly from the CLI, or through sic's image script.

NB: Operations are applied in a left-to-right order and are generally not commutative. This may be especially surprising when applying image operation via CLI options and flags.

๐Ÿ“œ image script

Use this method by using the --apply-operations "<operations>" (shorthand: -x) cli argument and providing statements which tell sic what operations should be applied on the image, for example:
sic -i input.jpg -o output.jpg --apply-operations "flip-horizontal; blur 10; resize 250 250"
When more than one image operation is provided, the separator ; should be used to separate each operation statement.

โœ๏ธ CLI ops

Use this method by providing cli image operation arguments, such as --blur and --crop, directly.
If we use the cli operations method the previously shown example becomes:
sic -i input.png -o output.jpg --flip-horizontal --blur 10 --resize 250 250


Available image operations
operations syntax^1 description
blur blur <fp> Performs a Gaussian blur on the image (more info). An argument below 0.0, will use 1.0 instead.
brighten brighten <int> Create a brightened version of the image.
contrast contrast <fp> Adjust the contrast of the image.
crop crop <uint> <uint> <uint> <uint> Syntax: crop <lx> <ly> <rx> <ry>, where lx is top left corner x pixel coordinate starting at 0, ly is the top left corner y pixel coordinate starting at 0, rx is the bottom right corner x pixel coordinate and ry is the bottom right corner y pixel coordinate. rx and ry should be larger than lx and ly respectively.
diff diff <path> Diff the input image against the argument image to show which pixels are the same (white), different (red) or not part of either image (transparent).
draw-text ^2 draw-text <string> <nv:coord> <nv:rgba> <nv:size> <nv:font> Draw text on top of an image (note: alpha-blending is not yet supported).
filter3x3 filter3x3 <fp9x> Apply a 3 by 3 convolution filter.
flip horizontal flip-horizontal Flips the image on the horizontal axis.
flip vertical flip-vertical Flips the image on the vertical axis.
gray scale grayscale Transform each pixel to only hold an intensity of light value. Reduces the color space to contain only gray monochromatic values.
horizontal gradient horizontal-gradient <nv:rgba> <nv:rgba> Fill and blend the image with a horizontal gradient from left to right.
hue rotate hue-rotate <int> Rotates the hue, argument is in degrees. Rotates <int>%360 degrees.
invert invert Invert the colours of an image.
overlay overlay <path> <uint> <uint> Overlay an image loaded from the provided argument path over the input image (at a certain position).
resize resize <uint> <uint> Resize the image to x by y pixels. Can both up- and downscale. Uses a lanczos3 sampling filter unless overridden. Prior to sic v0.11, the default sampling filter was gaussian.
> set preserve-aspect-ratio <bool> Enables preservation of the aspect ratio when resizing.
> set sampling-filter <value> When resizing use the <value> sampling filter. Choices are catmullrom, gaussian,lanczos3,nearest,triangle.
rotate90 rotate90 Rotate an image 90 degrees.
rotate180 rotate180 Rotate an image 180 degrees.
rotate270 rotate270 Rotate an image 270 degrees.
threshold threshold Apply automatic thresholding on the image.
unsharpen unsharpen <fp> <int> Applies an unsharpen mask to the image. The first parameter defines how much the image should be blurred and the second parameter defines a threshold. If the difference between the original and blurred image is at least the threshold, they will be subtracted from each other. Can be used to sharpen an image.
vertical gradient vertical-gradient <nv:rgba> <nv:rgba> Fill and blend the image with a vertical gradient from top to bottom.

^1 The syntax in the table applies to image script, but can also be used as a reference when using image operations via CLI arguments
^2 draw-text is only available when compiled with imageproc-ops feature

Image operation modifiers

For some operations, their behaviour can be adapted by setting an operation modifier. These modifiers can be overwritten and they can also be reset (to their default behaviour).

environment operation syntax description
set environment option set <option> [<args 0..n>] Enables the use of a modifier for an operation. Any operation which uses the value of the modifier will use the set modifier value instead of the default value. Can be overwritten by calling set again for the same operation and modifier specifier.
unset environment option del <option> Resets the modifier value. Any operation which looks at the value of this modifier will use the default value instead.

legend:

<byte>: an 8 bit unsigned integer (positive number in range 0-255
<uint>: a 32 bit unsigned integer (positive number)
<int>: a 32 bit signed integer (positive or negative number)
<fp>: a 32 bit floating-point number (real number)
<fp9x>: 9 succeeding 32 bit floating-point numbers
<path>: a qualified path to an image reachable from your current platform (the path should be surrounded by quotation marks, i.e. " or ')
<string>: a valid unicode string

<nv:coord>: a named value representing a coordinate (top left is (0, 0)), with syntax coord(<uint>, <uint>)
<nv:rgba>: a named value representing an RGBA color, with syntax: rgba(<byte>, <byte>, <byte>, <byte>)
<nv:size>: a named value representing a font size, with syntax: size(<fp>)
<nv:font>: a named value representing a (TrueType) font file location, with syntax: font(<path>)

Examples

blur example:
sic -i in.png -o out.png --apply-operations "blur 1.3;"
or
sic -i in.png -o out.png --blur 1.3

brighten example:
sic -i in.png -o out.png --apply-operations "brighten 2;"
or
sic -i in.png -o out.png --brighten 2

contrast example:
sic -i in.png -o out.png --apply-operations "contrast 0.7;"
or
sic -i in.png -o out.png --contrast 0.7

crop example:
sic -i in.png -o out.png --apply-operations "crop 0 0 10 10;"
or
sic -i in.png -o out.png --crop 0 0 10 10

diff example:
sic -i a.png -o diff_between_a_and_b.png --apply-operations "diff 'b.png'"
or
sic -i a.png -o diff_between_a_and_b.png --diff b.png

a b output
a b output

With an animated image:

a b output
a b output

draw-text example (requires build feature imageproc-ops):
sic -i in.png -o out.png --apply-operations "draw-text '<3' coord(10, 2) rgba(255, 0, 0, 255) size(14) font('./Lato-Regular.ttf')"
or
sic -i in.png -o out.png --draw-text "<3" "coord(10, 2)" "rgba(255, 0, 0, 255)" "size(14)" "font('Lato-Regular.ttf')"

input output
in out

filter3x3 example:
sic -i in.png -o out.png --apply-operations "filter3x3 -1 -1 0 -1 0 1 0 1 1"
or
sic -i in.png -o out.png --filter3x3 -1 -1 0 -1 0 1 0 1 1

flip horizontal example:
sic -i in.png -o out.png --apply-operations "flip-horizontal"
or
sic -i in.png -o out.png --flip-horizontal

flip vertical example:
sic -i in.png -o out.png --apply-operations "flip-vertical"
or
sic -i in.png -o out.png --flip-vertical

gray scale example:
sic -i in.png -o out.png --apply-operations "grayscale"
or
sic -i in.png -o out.png --grayscale

horizontal gradient example:
sic -i in.png -o out.png --apply-operations "horizontal-gradient rgba(255, 0, 0, 255) rgba(0, 0, 255, 255)"
or
sic -i in.png -o out.png --horizontal-gradient "rgba(255, 0, 0, 255)" "rgba(0, 0, 255, 255)"

hue rotate example:
sic -i in.png -o out.png --apply-operations "hue-rotate -90"
or
sic -i in.png -o out.png --hue-rotate -90

invert example:
sic -i in.png -o out.png --apply-operations "invert"
or
sic -i in.png -o out.png --invert

overlay example:
sic -i in.png -o out.png --apply-operations "overlay 'image.png' 10 10"
or
sic -i in.png -o out.png --overlay "image.png" 10 10

resize example:
sic -i in.png -o out.png --apply-operations "resize 100 100"
or
sic -i in.png -o out.png --resize 100 100

resize with preserve aspect ratio example:
sic -i in.png -o out.png --apply-operations "set preserve-aspect-ratio true; resize 100 100"
or
sic -i in.png -o out.png --preserve-aspect-ratio true --resize 100 100

resize with custom sampling filter (default is 'lanczos3') example:
sic -i in.png -o out.png --apply-operations "set sampling-filter triangle; resize 100 100"
or
sic -i in.png -o out.png --sampling-filter triangle --resize 100 100

rotate 90 degree example:
sic -i in.png -o out.png --apply-operations "rotate90"
or
sic -i in.png -o out.png --rotate90

rotate 180 degree example:
sic -i in.png -o out.png --apply-operations "rotate180"
or
sic -i in.png -o out.png --rotate180

rotate 270 degree example:
sic -i in.png -o out.png --apply-operations "rotate270"
or
sic -i in.png -o out.png --rotate270

threshold example:
sic -i in.png -o out.png --apply-operations "threshold"
or
sic -i in.png -o out.png --threshold

unsharpen example:
sic -i in.png -o out.png --apply-operations "unsharpen -0.7 1"
or
sic -i in.png -o out.png --unsharpen -0.7 1

vertical gradient example:
sic -i in.png -o out.png --apply-operations "vertical-gradient rgba(255, 0, 0, 255) rgba(0, 0, 255, 255)"
or
sic -i in.png -o out.png --vertical-gradient "rgba(255, 0, 0, 255)" "rgba(0, 0, 255, 255)"

example with multiple image operations which are applied from left-to-right:
sic -i in.png -o out.png --apply-operations "rotate180; flip-horizontal; set sampling-filter nearest; resize 75 80; hue-rotate 75"
or
sic -i in.png -o out.png --rotate180 --flip-horizontal --sampling-filter nearest --resize 75 80 --hue-rotate 75


Other resources on image operations

For additional information on available options and flags, run sic --help.

License

Licensed under either of

at your option.

Contribution

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

Suggestions, Questions, Bugs

Feel free to open an issue ๐Ÿ“ฌ if you have a suggestion, a question or found a bug =).

๐ŸŽธ ๐ŸŽบ ๐ŸŽป ๐ŸŽท

sic's People

Contributors

artanu avatar bors[bot] avatar clanghout avatar dependabot-preview[bot] avatar dependabot[bot] avatar foresterre avatar luxrck avatar orhun avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

sic's Issues

Enhance user-like testing beyond 0.8.0

Succeeds #71.

Currently 2 stages in the manually written pipeline use std::process:exit(0) to exit successfully, but early, from the pipeline. The usage of this exit()/1 function however also quits out of a test binary.
The pipeline should be streamlined by making using of Result and the try operator for early breaking.

The try operator itself (std::ops::Try) is unfortunately currently marked as unstable [1].
An alternative would be to use std::convert::From instead.

[1] https://doc.rust-lang.org/std/ops/trait.Try.html


PR: (none)
Previous issue: #71

Update help to contain all image operations.

  • clap --help updated

  • General operations usage (--script) documented

Individual operations documented:

  • blur
  • brighten
  • huerotate
  • contrast
  • filter3x3
  • fliph
  • flipv
  • grayscale
  • invert
  • resize
  • rotate180
  • rotate270
  • rotate90
  • unsharpen

Possibly write the docs in a separate help__image_operations.txt file and use include_str!()/1 macro.

Add ability to revert a `set` environment item to its default.

With set <OPTION ARGS> we can set a option with argument(s) or a flag and store it in the image command environment. We can use the same to update it. This enables us to go back to the default if we know which one that is. This feature enables us to remove the option setting from the environment thereby reverting back to the default.

Initial user-like testing (before release 0.8.0)

Make a test suite which tests user like cli options and try to verify whether results are correct.

(1) Use Command or similar to run stuff like cargo run -- <options or flags, for example cargo run -- -H index.

Or:

(2) Make the Clap App return from a function or similar and put the other items in main() also in a function (say A()). Then you can call the clap app with get_matches_from(...) and call A() without having to call main.

  • (+) Can be used as a normal test
  • (+) Does not rely on Command / OS semantics
  • (-) Is not fully run like a user since it doesn't call the sic executable

Choice:
As process::exit()/1 is used for some commands (e.g. after printing the license or a help command), I used (1) for the commands which do this; (2) would not have returned a value and instead quits out of testing for all tests in the particular suite.
A better solution than using process::exit()/1 shouldbe used in the future.
See tracking issue #? for this.


This issue tracks an initial version of the above; just enough to have some idea of whether 0.8.0 can be released.


PR: #73, #74, #75
Succeeding tracking issue: #77

Bug: output is currently required to be set in all cases

Because

Config {
 ...,
 output: matches
            .value_of("output_file")
            .expect("An OUTPUT was expected, but none was given.")
            .into(),
}

Example which breaks: cargo run -- -H index

An output will be expected in all cases even if it is not required.

Include licenses from dependencies as `--licenses-dependencies` or similar in binaries.

Decision: Will keep manual releasing, as described by https://github.com/foresterre/sic/blob/master/RELEASE_STEPS.md. Did add a cargo-make task called release (cargo make release) which builds a binary release, with the licenses from dependencies included (this will be included as a clap command very soon).
The licenses will not be in the tree, as they exist in their respective dependency source code and this repo 'only' defines a dependency on such a library (i.e. it does not include its source code in tree).
Plus, it would be a 8000+ line file in the root which would need to be updated regularly.
By including the licenses in the binary, and not having their source code in my git repository, I think I do comply with MIT License: "The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software." and same for BSD-3-clause's binary form, and Apache 2.0 "Object" form.

Options available / home make option:

All three options have some desirable features.
cargo-bom can print out the full license text
cargo-license can print out license titles ("MIT", "Unlicense") sorted for all crates (License (n): < n crates>
cargo-lichking can do the same as cargo-license, and it tries to also provide validity for compatible licenses, but I'm almost certain that BSD-3-Clause is compatible with MIT, and it reports incompatibilities based on these two licenses only (if you comply with the BSD-3-clause extra clause, there shouldn't be a problem, as far as I understand).

Include options

  • Include full license texts in binary (cargo-bom)
  • Include full license texts in binary, but max one per license (would require some custom steps)
  • Alternatively, release zip/tgz with license file.

Straightforward releasing

  • build.rs
  • small python 3 script (prefer not to be dependable)
  • cargo-make + build.rs

Impl

  • Use include_str!()/1 to include full result on release.

  • I am not a lawyer, so let's try to make the licenses of [permissive] dependencies as accessible as possible, as I am not 100% sure what the best way is to comply with those software licenses. Looking at other people, keeping license text of dependencies in place seems to be fine enough for MIT, but then again, I'm not 100% sure if it is enough. Additionally, it is great software sic depends on, so they_do_ deserve a mention nonetheless.

Apply operations: require separator `;` between operations.

Allows for easier parsing and allows to add future additions more easily.
However, if this change is preferred, it should be applied sooner rather than later.

Should it be a true separator, i.e. be optional for the last command?


PR: #94
related issue(s): -

Optimization pass

Right now, getting the program to work correctly, is the most important. But one day, I would like to take a better look at the actual performance. Perhaps most of the image operations could happen in-place for example. As I am still learning Rust, I might make unfortunate performance worsening mistakes.

For now this issue won't get a milestone; but is kept as a reminder of work to do.

Upstream dependency "proc_macro2" fails to compile (through cargo install / crates.io).

given error message:

error[E0599]: no method named `extend` found for type `proc_macro::TokenStream` in the current scope
   --> /home/albus/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.19/src/unstable.rs:225:23
    |
225 |                 first.extend(streams.map(|s| {
    |                       ^^^^^^

error[E0599]: no method named `extend` found for type `&mut proc_macro::TokenStream` in the current scope
   --> /home/albus/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.19/src/unstable.rs:254:25
    |
254 |                     tts.extend(
    |                         ^^^^^^

error[E0599]: no method named `extend` found for type `&mut proc_macro::TokenStream` in the current scope
   --> /home/albus/.cargo/registry/src/github.com-1ecc6299db9ec823/proc-macro2-0.4.19/src/unstable.rs:287:25
    |
287 |                     tts.extend(streams.into_iter().map(|stream| stream.unwrap_nightly()));
    |                         ^^^^^^

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0599`.
error: Could not compile `proc-macro2`.
warning: build failed, waiting for other jobs to finish...
error: failed to compile `sic v0.7.2`, intermediate artifacts can be found at `/tmp/cargo-installB7zHI2`

rename --script

Rename --script to more clearly express its purpose.

Purpose

  • Apply image operations on an image

Options/ideas

  • --apply (-A)
    • (+) short
    • (-) vague
  • --apply-operations (-A)
    • (+) clear, with shorthand reasonable length of parameter name doesn't matter as much
    • (-) long
  • --actions

--

choice: --apply-operations with shorthand -A.

CLI user manual

The CLI user manual could use some love.

  • The -H <topic> option should only allow the available pages
  • Pages should be able to be printed out with and without page header (*1); for example so that the -h option can be printed without header. (*2)
    • Alternatively: remove the page header altogether: sic is a cli after all
  • Page headers should be generated, not included in every page source file. (*2)
  • Contents: define min, max values
  • Improve help texts
  • Improve/sort out formatting; perhaps commonmark isn't the best choice :)

(*1):
Header for the following page is:

User Manual
===========

Page: 'script'
Category: 'cli option'

(*2):
Rethink the use of page headers and "pages" in general; study prior works on this topic

Accept different sampling filters on resize

syntax:

  • Must have a syntax limited to tokens available in the ASCII set
  • Must support letters, numbers and some type of word separator
  • Must be unordered
  • Must support both Key Value and Flag
  • Must be reusable as syntax (i.e. like a general "data structure") with sic script v1
  • Should be accessible to type from the command line
  • Should be accessible to type within a file
  • Should be easy to read

Ideas for syntax:

  • resize x y <optional format>

  • resize 4 5 == resize 4 5 :sampling_filter gaussian

  • resize 4 5 :sampling_filter lanczos3

  • resize 4 5 -sampling-filter lanczos3

  • resize 4 5 +sampling-filter lanczos3

  • resize 4 5 #sampling-filter lanczos3

  • resize 4 5 (sampling-filter: lanczos3)

  • resize 4 5 {sampling-filter: lanczos3}

selected choice:

  • setopt resize <option> <option value>
    • setflag resize <flag>
  • resize <x> <y>

examples:
cargo run -- --apply-operations "setopt resize sampling_filter triangle;resize 50 50" ./resources/bwlines.png ./target/o.png

--

PR: #102
Related:

  • #45 (Add keep-aspect-ratio flag or option to resize)

Release 0.9.0

Changes from 0.8.1 to 0.9.0:

  • Add image operation option functionality
    Enable an option by using set and disable it again by using del.
    Available options:
    • set resize keep_aspect_ratio
    • set resize sampling_filter <value>
  • Add 'crop' image operation
  • Add '-x' as shorthand for, and set '-A' to be an alias for '--apply-operations'.
  • โš ๏ธ Breaking change: require the ; separator between image operations
  • โš ๏ธ Breaking change: renamed --force-format to --output-format
  • โš ๏ธ Breaking change: renamed --script to --apply-operations

Problems encountered & their resolutions

Todo:

  • #108 Add -x or -X alias

Blocking:

  • #111 dep licenses file duplication

Release checklist

Create Release PR

  • Included this checklist. Already a step complete! ๐Ÿ˜‰

Verify

  • Verify formatting with cargo +nightly fmt.
  • Does cargo test succeed?
  • Verify image output of images produced with cargo test --features output-test-images.
  • Do all CI runs complete successfully?

Update version number

  • Define update version number as described here.
  • Update the version number in Cargo.toml.
  • The Clap App version number in src/main.rs will be equal to the version number in Cargo.toml.

Update the dependency licenses to be included in the binary as per their licenses

  • Run cargo run --example update_dep_licenses to update the licenses of dependencies, which will be included in a binary build.

Verify again

Same as above.

  • Completed!

Merge Release PR

If no blocking issues are detected and this checklist is complete,
we can move on to the next step.

Publish & Upload

  • Run cargo package and check the resulting .crate
  • Run cargo publish and verify the result

Release, Tag & Binaries

  • Create a release with a version tag on the github release page

    • tags are equal to crate version number e.g. 0.5.1
    • release title is sic-<version> e.g. sic-0.5.1
  • Add Windows and Linux (Ubuntu compiled) binaries to the release

    • compile with cargo build --release

Release steps


PR: #110

Add `convert` and `save` to script.

Depends on: #10, #36
Todo: look at possibilities, check what works from a usability standpoint.

Make

  • convert <format>
    and
  • save <file-path>
    part of script.

This might make <out> from sic <in> <out> <options> optional.

save example grammar (simplified, depends on os/filesystem):

whitespace = _{ (" " | "\t" | "\n" | "\r\n") }
sep = _{ ";" }


uint = @{ digit+ }
digit = { '0'..'9' }
path = ${ ( ('a'..'z') | ('A'..'Z') | digit | "." )+  }

operation_sequence = _{ (operation ~ sep?)+ }

operation = _{ blur | flip_horizontal | flip_vertical | resize | save }

blur = ${ ^"blur" ~ whitespace ~ uint}
flip_horizontal = { ^"flip_horizontal" }
flip_vertical = { ^"flip_vertical" }
resize = ${ ^"resize" ~ whitespace ~ uint ~ whitespace ~ uint }
save = ${ ^"save" ~ whitespace ~ path }

main = _{ soi ~ operation_sequence ~ eoi }

Accept different versions of supported formats

  • Accept different versions of supported formats

The following options are parameters defined by ImageOutputFormat.

  • JPEG:
    • quality
  • PNM:
    • ascii/binary
    • subtype

Currently, sic uses a default value, e.g. quality=80 for jpeg. This issue/pr experiments with user facing settings and in time will decide how to enable a user to provide arguments for these parameters.

Decision:

  • Use a single flag for ascii for pbm, pgm, ppm and an option for jpeg quality (no other types have parameters)
    • requires less user input
    • is more straightforward
    • provides no input duplication
  • format (and in the case of PNM, subtype) is decided to be set using --force-format (-f) if provided or .<ext> extension if not provided. Will error on invalid input, such as no extension and no -f, or an unknown format specifier or extension.
  • format specifiers are the same as the extensions

Add --preview flag to preview the image in the terminal.

Example usage sic --preview input.png output.png

Displays a preview of the image after image processing.

TODO decide:

  • Can (not) be combined with stdout output or print to stderr.
  • Character to use for display
  • Do not require [output file]
  • Settings file / settings option to enable launching preview with an external tool

Detail of preview and protocols

Middleware like pipeline

Experiment with a linear single image middleware enabled pipeline

  • Prior use case example: How do web frameworks do middleware for requests?
  • Will it be useful to apply (and transform if required) it as sic's (linear single image) pipeline?
  • Can it be useful for batch processing?
  • Pros/cons?
  • Other options?

Avoid early process::exit for enhanced testability

In #71, I experienced that using std::process::exit/1 to early exit from the process can be unfortunate for writing integration tests around sic_lib. Using process::exit/1 quits out of the full test module, i.e. it stops running the full test module.


PR: (none)
Closed on Sept. 27, 2019: this issue is no longer relevant

Modularize lib crate with sub crates: sic edition

  • Parser module & combostew re-export (issue: #119 , PR: #117)
  • module: help (issue: #121, PR: #122)
    • remove ProcessWithConfig from crate (issue: #?, PR: #?)

Future:

Look into adding the combostew modules as crates in this repository. Publish these crates as appropriate on crates.io, use from sic with path = ".../combostew_{X}" :

  • combostew >> module: n_0
  • combostew >> module: n_1
  • combostew >> module: n_2

Improve error handling

Improve error handling for example by defining an Error type. Possibly use the 'failure' crate.

sic: wishlist

  • Multi-format flags [complete, issue: #11, pr: #60]
  • Better image operations pipeline (but ProcessWithConfig will do for now) [only the user manual uses ProcessWithConfig right now, phasing out]
  • Sort out immutable/mutable for DynamicImage references [complete]
  • Batch processing
  • Script options as cli flags/options [complete, issue: #85 , pr: #144]
  • GUI (separate binary)
  • Improve error handling
  • Parallelism
  • Pipelining
  • Remove as much heap allocations as possible
  • Some kind of benchmark to compare the performance difference of changes
  • Modular crates :-) [complete]

2019-06-06:

  • Set custom options from the cli, for example: --default-resize-sampling-filter <value> [complete]
  • Add an interactive mode which launches a gui (e.g. miniview) to display intermediate results, should probably include an 'undo'; possibly make it separate from sic?

Add image operations as cli options/flags

Should each image operation also be available with a cli option or flag?

Pro:

  • It might be expected
  • Especially accessible when using just one or very few operations
  • Easily generate shell completions (see also #76 )

Contra:

  • Ordering of flags/options won't be evaluated + applied we can work around this
  • Multiple ways to access the same functionality; i.e. no longer one way to do it
  • Difficult syntax if also adding optional parameters within the same operation flag/option; or extra configuration flags / options may be required. We'll use extra cli arg in line with the syntax used for apply-operations.

Consequences:

  • No definitive order of applied operations when not using --script, outside of --script; so cli flags and options will have an undefined ordering while any image operation within the --script cli option will still have linear ordering.

Questions open:

  • Should the operation flags be able to be used together with --script? no, we use one or the other
  • If yes: should --script override the selected flags? or the other way around? or be undefined?

Impl:

  • What are the possibilities for defining an operation interface once for each operation? e.g. for blur, can
    we have a single definition and implementation of the interface to the command for both --blur <i32> and script:blur <i32>?

  • Get the order by processing index_of for every argument?

0.7.1 fails to build from crates.io

Install with cargo install --force sic fails;

Probably because if you use cargo install, no cargo.lock is available to run cargo-bom upon?

Temporary resolution: cargo yank --vers 0.7.1

Build log:

PS> cargo install --force sic
    Updating registry `https://github.com/rust-lang/crates.io-index`
 Downloading sic v0.7.1
  Installing sic v0.7.1
   Compiling version_check v0.1.4
   Compiling cfg-if v0.1.5
   Compiling nodrop v0.1.12
   Compiling scopeguard v0.3.3
   Compiling memoffset v0.2.1
   Compiling proc-macro2 v0.4.18
   Compiling num-traits v0.2.5
   Compiling num-integer v0.1.39
   Compiling rayon-core v1.4.1
   Compiling libc v0.2.43
   Compiling unicode-xid v0.1.0
   Compiling winapi v0.3.5
   Compiling num-iter v0.1.37
   Compiling rayon v1.0.2
   Compiling unicode-xid v0.0.4
   Compiling either v1.5.0
   Compiling byteorder v1.2.6
   Compiling adler32 v1.0.3
   Compiling color_quant v1.0.1
   Compiling bitflags v1.0.4
   Compiling unicode-width v0.1.5
   Compiling lzw v0.10.0
   Compiling quote v0.3.15
   Compiling sic v0.7.1
   Compiling scoped_threadpool v0.1.9
   Compiling strsim v0.7.0
   Compiling vec_map v0.8.1
   Compiling pest v1.0.6
   Compiling crossbeam-utils v0.2.2
   Compiling arrayvec v0.4.7
   Compiling num_cpus v1.8.0
   Compiling lazy_static v1.1.0
   Compiling synom v0.11.3
   Compiling inflate v0.4.3
   Compiling textwrap v0.10.0
   Compiling deflate v0.7.18
   Compiling gif v0.10.0
error: failed to run custom build command for `sic v0.7.1`
process didn't exit successfully: `C:\Users\$env:UserName\AppData\Local\Temp\cargo-installWaWBU3\release\build\sic-3e43ea185127d3dc\build-script-build` (exit code: 101)
--- stdout
Starting the pre-processing of a `sic` build.
cargo-bom path found at: "C:\\Users\\$env:UserName\\.cargo\\bin\\cargo-bom.exe"

--- stderr
thread 'main' panicked at 'Unable to create dependency license file.: Os { code: 3, kind: NotFound, message: "The system cannot find the path specified." }', libcore\result.rs:983:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.

warning: build failed, waiting for other jobs to finish...
error: failed to compile `sic v0.7.1`, intermediate artifacts can be found at `C:\Users\$env:UserName\AppData\Local\Temp\cargo-installWaWBU3`

Caused by:
  build failed

Add crop command

  • Add crop to --script
  • Crop is not the same as resize,
  • i.e. it selects a sub canvas within the image canvas and crops to that sub canvas

Add other filter types as option

Suggested syntax

--cfg-resize-filter-type <value>

currently defaults to Gaussian

options:

  • "near" => FilterType::Nearest
  • "tri" => FilterType::Triangle
  • "cmr" => FilterType::CatmullRom
  • "gauss" =>FilterType::Gaussian
  • "lcz2" => FilterType::Lanczos3

Could also be syntactically applied to the declarative image operation script.

Release 0.8.0

Release steps


Changes from 0.7.x to 0.8.0:

  • Accept user set options for the image output format. (issue: #11, PR: #60)
  • Add automatic color type adjustment for output format (if output format is incompatible with color type of the image buffer), including a flag to turn it off. (part of PR: #60, commit: 3ec068)
  • Upgraded pest crate from 1.0.x to 2.x.x (issue: #62 , PR: #66)
  • Upgraded image crate from 0.19.x to 0.20.x (issue: #67, PR: #63)
  • Update Rust edition to 2018 (issue: _, PR #54)

Problems encountered & their resolutions

Blocking:

  • #69: output_file is currently required to be set in all cases, but should not be required if arg defines required_unless_one with output_file as argument.

  • Because of #69, I decided to move an initial version of #71 (various cli commands automatically tested) forward, to be included in 0.8.0


Release checklist

Verify

  • Verify that each PR has run cargo fmt.
  • Does cargo test succeed?
  • Does cargo run -- resources/bwlines.png target/out.jpg --script "blur 10; flipv; resize 10 10;" complete successfully and produce a 10x10 blurred and flipped vertically JPEG image?
  • Verify image output of images produced with cargo test --features output-test-images.
  • Do all CI runs complete successfully?

Update version number

  • Define update version number as described here
  • Update the version number in Cargo.toml
  • Update the version number in src/main.rs at the Clap App .about()/1

Update the dependency licenses to be included in the binary as per their licenses.

  • Run cargo run --example update_dep_licenses to update the licenses of dependencies, which will be included in a binary build.

Publish & Upload

  • Run cargo package and check the resulting .crate
  • Run cargo publish and verify the result

Release, Tag & Binaries

  • Create a release with a version tag on the github release page

    • tags are equal to crate version number e.g. 0.5.1
    • release title is sic-<version> e.g. sic-0.5.1
  • Add Windows and Linux (Ubuntu compiled) binaries to the release

    • compile with cargo build --release

PR: #70

Remove (and replace?) the currently built in user manual.

Reasons to remove / replace:

  • It is not up to date
  • It is not very flexible
  • It is not very readable
  • It requires updating user documentation in various places

The documentation should somehow be replaced by similar (probably more complete) user facing documentation, preferably generated so that writing it once is enough :).

This issue tracks the removal. Another issue will need to be opened for a replacement.

Release 0.8.1

Changes from 0.8.0 to 0.8.1:

  • Update sic to be compatible with a stable Rust compiler. (issue: #79, PR: #80)

Problems encountered & their resolutions

Blocking:

  • Which version number for this mini release? 0.8.1 or 0.9.0?

    Why?
    • No direct functionality is introduced
    • No incorrect behavior is fixed.

But the Rust description page says:

but if you make breaking changes, increment the minor version. In Rust, breaking changes include adding fields to structs or variants to enums.

No breaking changes are made from a user perspective, so I decided to use version 0.8.1.
Perhaps there are multiple ways you can look at this, but I didn't think it is worth it for this change.


Release checklist

Create Release PR

  • Included this checklist. Already a step complete! ๐Ÿ˜‰

Verify

  • Verify formatting with cargo +nightly fmt.
  • Does cargo test succeed?
  • Verify image output of images produced with cargo test --features output-test-images.
  • Do all CI runs complete successfully?

Update version number

  • Define update version number as described here.
  • Update the version number in Cargo.toml.
  • The Clap App version number in src/main.rs will be equal to the version number in Cargo.toml.

Update the dependency licenses to be included in the binary as per their licenses

  • Run cargo run --example update_dep_licenses to update the licenses of dependencies, which will be included in a binary build.

Verify again

Same as above.

  • Completed!

Merge Release PR

If no blocking issues are detected and this checklist is complete,
we can move on to the next step.

Publish & Upload

  • Run cargo package and check the resulting .crate
  • Run cargo publish and verify the result

Release, Tag & Binaries

  • Create a release with a version tag on the github release page

    • tags are equal to crate version number e.g. 0.5.1
    • release title is sic-<version> e.g. sic-0.5.1
  • Add Windows and Linux (Ubuntu compiled) binaries to the release

    • compile with cargo build --release

Release steps


PR: #81

"macro language" for image processing operations

  • Add 'macro language' for image processing functions support

  • Command line syntax? ideas:

    • sic in out.ext --script "invert; rotate180; flip_vertical"
    • sic in out.ext --script-from-file example.sic
    • sic in out -f PNG --map "invert; rotate180"

See #8 (provides base layer for the image script, plus the first 4 operations).

Current grammar: https://github.com/foresterre/sic/blob/master/src/operations/grammar.pest
Useful grammar editor: https://pest-parser.github.io/#editor
Grammar syntax: https://pest-parser.github.io/book/grammars/syntax.html

Operations implemented:

  • blur #8
  • brighten #20
  • huerotate #21
  • contrast #25
  • crop use resize
  • filter3x3 #40
  • flip_horizontal fliph #8 #30
  • flip_vertical flipv #8 #30
  • grayscale #28
  • invert #31
  • resize #8
  • rotate180 #18
  • rotate270 #18
  • rotate90 #18
  • unsharpen #38

Crop whitespace from outer area of image.

When saving images, sometimes, the image size is bigger than the actual image. An example would be a logo on a white background. A functionality to automatically crop the image so that the boundaries of the image are aligned with the content can be very helpful.

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.