Command line batch image cropping tool - image

is there any lightweight command line batch image cropping tool(Linux or Windows) which can handle a variety of the formats ?

In Linux you can use
mogrify -crop {Width}x{Height}+{X}+{Y} +repage image.png
for CLI image manipulation

Imagemagick's convert does the trick for me (and much more than cropping):
convert -crop +100+10 in.jpg out.jpg
crops 100 pixels off the left border, 10 pixels from the top.
convert -crop -100+0 in.jpg out.jpg
crops 100 pixels off the right, and so on. The Imagemagick website knows more:
http://www.imagemagick.org/Usage/crop/#crop

Imagemagick is what you want -- tried and true.

I found nconvert pretty handy so far.

for f in final/**/*;
do
convert -crop 950x654+0+660 "$f" "${f%.jpg}".jpg
done
This script loops through all the sub-folders and crops the .jpg files.

macOS has sips image processing tool integrated. Cropping functions available are:
-c, --cropToHeightWidth pixelsH pixelsW
--cropOffset offsetY offsetH

Easy with sips: just set the offset to start the cropping:
sips --cropOffset 1 1 -c <height> <width> -o output.png input.png

I have scanned some pages and all ~130 pages needs the lower ~1/8 of the page cut off.
Using mogrify didn't work for me,
a#a-NC210-NC110:/media/a/LG/AC/Learn/Math/Calculus/Workshop/clockwise/aa$ mogrify -quality 100 -crop 2592×1850+0+0 *.jpg
mogrify.im6: invalid argument for option `2592×1850+0+0': -crop # error/mogrify.c/MogrifyImageCommand/4232.
However convert did:
a#a-NC210-NC110:~/Pictures/aa$ convert '*.jpg[2596x1825+0+0]' letter%01d.jpg
a#a-NC210-NC110:~/Pictures/aa$
I learnt this here under the Inline Image Crop section.
Notice my syntax: I had to put my geometry in brackets: [].
Using the successful syntax above but with mogrify simply didn't work, producing:
a#a-NC210-NC110:~/Pictures/aa$ mogrify '*.jpg[2596x1825+0+0]' letter%01d.jpg
mogrify.im6: unable to open image `letter%01d.jpg': No such file or directory # error/blob.c/OpenBlob/2638.
Linux a-NC210-NC110 3.13.0-32-generic #57-Ubuntu SMP Tue Jul 15 03:51:12 UTC 2014 i686 i686 i686 GNU/Linux
Lubuntu 14.04 LTS

Related

ImageMagick: guess raw image height

I'm using convert utility from ImageMagick to convert raw image bytes to usable image format such as PNG. My raw files are generated by code, so there is no any headers, just pure pixels.
In order to convert my image I'm using command:
$ convert -depth 1 -size 576x391 -identify gray:image.raw image.png
gray:image.raw=>image.raw GRAY 576x391 576x391+0+0 1-bit Gray 28152B 0.010u 0:00.009
The width is fixed and pretty known for me. However I have to evaluate the height of the image from the file size each time which is annoying.
Without height specified or if wrong height is specified the utility compains:
$ convert -depth 1 -size 576 -identify gray:image.raw image.png
convert-im6.q16: must specify image size `image.raw' # error/gray.c/ReadGRAYImage/143.
convert-im6.q16: no images defined `image.png' # error/convert.c/ConvertImageCommand/3258.
$ convert -depth 1 -size 576x390 -identify gray:iphone.raw iphone.png
convert-im6.q16: unexpected end-of-file `image.raw': No such file or directory # error/gray.c/ReadGRAYImage/237.
convert-im6.q16: no images defined `image.png' # error/convert.c/ConvertImageCommand/3258.
So I wonder is there a way to automatically detect the image height based on the file/blob size?
A couple of ideas...
You may not be aware of the NetPBM format, but it is very simple and you may be able to change your software that creates the raw images so that it directly generates PBM format images which are readable and useable by OpenCV, Photoshop, GIMP, feh, eog and ImageMagick of course. It would not require any libraries or extra dependencies in your software, all you need to do is put a textual PBM header on the front, so your file looks like this:
P4
576 391
... YOUR EXISTING BINARY DATA ...
Do not forget to put newlines (i.e. linefeed character) after P4 and after 391.
You can try it for yourself and add a header onto one of your files like this and then view it with GIMP or other tool:
printf "P4\n576 391\n" > image.pbm
cat image.raw >> image.pbm
If you prefer a one-liner, just use a bash command grouping like this - which is equivalent to the 2 lines above:
{ printf "P4\n576 391\n"; cat image.raw; } > image.pbm
Be careful to have all the spaces and semi-colons exactly as I have them!
Another idea, just putting some meat on Fred's answer, might be the following one-liner which uses a bash arithmetic context and a bash command substitution, you can do this:
convert -depth 1 -size "576x$(($(stat -c "%s" image.raw)*8/576))" gray:image.raw image.png
Note that if you are on macOS, stat is a little different, so you may prefer the slightly less efficient, but more portable:
convert -depth 1 -size "576x$(($(wc -c < image.raw)*8/576))" gray:image.raw image.png
You have to know the -depth and width to compute the height for ImageMagick raw format. If depth is 1, then your image is binary (b/w). So height = 8 * file size (in B)/(width). 28152*8/391 = 576

ImageMagick error with montage command

I'm stitching 8 images of 8k by 8k pixels in a row using the montage command.
This is what I enter in:
montage -mode concatenate -limit area 0 -tile x1 image1.png image2.png image3.png image4.png image5.png image6.png image7.png image8.png out1.png
This is the error I get out:
montage: magick/quantum.c:215: DestroyQuantumInfo: Assertion `quantum_info->signature == 0xabacadabUL' failed.
Abort
Can anyone help? Thanks
You may get on better with this command which does what I think you are trying to do:
convert +append image{1..8}.png out.png
As you can see from the following identify command, the images have been laid out side-by-side to make an image 64k pixels wide as a result of the +append command. Just FYI, use -append to lay them out one above the other in a 64k pixel tall stack.
identify out.png
out.png PNG 64000x8000 64000x8000+0+0 8-bit sRGB 2c 62.4KB 0.000u 0:00.000
Your originally posted command also works fine on my ImageMagick Version:
ImageMagick 6.8.9-5 Q16 x86_64 2014-07-29

Get offset from Imagemagick trim

I am using Imagemagick to trim some png files (remove transparent border), I use the command below:
convert -debug Coder longyan_1.png -trim longyan_1.trimed.png
Then the tool gave me a trimed image as I wanted, but I want more information about the trim offset.
In the debug info I can see the line below:
2014-05-10T14:32:42+08:00 0:04.860 4.840u 6.8.7 Coder convert[49089]: png.c/WriteOnePNGImage/10747/Coder
Setting up oFFs chunk with x=181, y=118, units=0
The "x,y" info is exactly what I want, but the debug info is too much to deal with, is there any Imagick native API or any other tricks to get the offset info?
I think you actually need the %# trim box info, which you get like this:
convert image.png -format "%#" info:
233x375+60+51
or equally, maybe even more succinctly:
identify -format "%#" image.png
233x375+60+51
So, to test it out, I create an image like this:
convert -size 400x200 xc:red -size 80x40 xc:yellow -gravity center -composite image.png
And then ask ImageMagick how it would trim it:
convert image.png -format "%#" info:
80x40+160+80
I am sure that there are more complicated ways to do this but, if you just get the offset info, you can use grep:
$ convert -debug Coder longyan_1.png -trim longyan_1.trimed.png 2>&1 | grep "Setting up oFFs chunk"
Setting up oFFs chunk with x=181, y=118, units=0
If you want to shorten and/or reformat the output still more, you can use sed. For example:
$ convert -debug Coder longyan_1.png -trim longyan_1.trimed.png 2>&1 | sed -n '/Setting up oFFs chunk/ s/.*x=/x=/p'
x=181, y=118, units=0

graphicsmagick composite and crop in the same command

I need to get a specific crop of an image and put it over another image at a certain position and resized.
I can crop the first image and save it to a file in one command and then I can composite the 2 images in another command.
However, I would like to do it in a single command - is this possible with graphicsmagick and how?
Here are the 2 commands I am using atm:
gm convert -crop 1457x973+254+413 amber.jpg tmp.jpg
gm composite -geometry 6000x4000+600+600 tmp.jpg lux_bg.png out.jpg
The reason for wanting this is to avoid writing to disk then reading again when all this could be done in memory.
With ImageMagick, for example, the same 2 commands would be written in a single command like this:
convert lux_bg.png \( amber.jpg -crop 1457x973+254+413 \) -geometry 6000x4000+600+600 -composite out.jpg
I am doing this with ImageMagick for now but would love to do it with GraphicsMagick.
If your reason is simply to avoid creating a temporary file, you can still do it with two commands by constructing 'pipelines' (a great concept invented by, afaik, Douglas McIlroy around 1964):
gm convert -crop 1457x973+254+413 amber.jpg - | gm composite -geometry 6000x4000+600+600 - lux_bg.png out.jpg
hint: note the two - dashes in the two commands, and the | pipe
since the - can be used to mean the standard output and input in the two commands respectively.
This means that no file is created, all should happen in the memory.
You can find this in the help (gm -help convert | grep -i -e out -B 1):
Specify 'file' as '-' for standard input or output.
The use of - is common in unix-likes and must have been inspired by, or by something related to, the POSIX standard's Utility Syntax Guidelines.
Have you tried && operator? Your command should become:
gm convert -crop 1457x973+254+413 amber.jpg tmp.jpg && gm composite -geometry 6000x4000+600+600 tmp.jpg lux_bg.png out.jpg

Generating x number of pictures

I need to generate pictures with a certain size (in pixels). Each picture will have an incrementing number in it. That is all that will be in the picture, a number. I've been thinking of using photoshop but I have no idea how the scripting works. Any suggestions or examples I could use?
Try using ImageMagick (http://www.imagemagick.org) and its text handling feautures (http://www.imagemagick.org/Usage/text/).
Here is a way of doing that using ImageMagick:
#!/bin/bash
for i in {0..3}; do
echo Generating $i...
convert -size 256x256 xc:black \
-gravity south -background orange -splice 0x20 -annotate +0+2 "$i" image-$i.png
done
And the result:

Resources