How to chop selective images using ImageMagick - imagemagick

I would like to chop screenshot images that are specifically of mobile. And bundle them into pdf in sequence.
#!/bin/sh
desktop_path=./screenshots/desktop/
mobile_path=./screenshots/mobile/
pdf_path=./pdf/
convert ${desktop_path}screenshot-1.png ${desktop_path}screenshot-2.png ${desktop_path}screenshot-3.png ${desktop_path}screenshot-4.png ${desktop_path}screenshot-5.png ${desktop_path}screenshot-6.png ${desktop_path}screenshot-7.png ${desktop_path}screenshot-8.png ${desktop_path}screenshot-9.png ${desktop_path}screenshot-10.png ${desktop_path}screenshot-11.png ${desktop_path}screenshot-12.png ${desktop_path}screenshot-13.png -chop 0x0 ${mobile_path}screenshot-1.png ${mobile_path}screenshot-2.png ${mobile_path}screenshot-3.png ${mobile_path}screenshot-4.png ${mobile_path}screenshot-5.png ${mobile_path}screenshot-6.png ${mobile_path}screenshot-7.png ${mobile_path}screenshot-8.png ${mobile_path}screenshot-9.png ${mobile_path}screenshot-10.png ${mobile_path}screenshot-11.png ${mobile_path}screenshot-12.png ${mobile_path}screenshot-13.png ${mobile_path}screenshot-14.png -chop 0x43 ${pdf_path}packets-temp.pdf
The issue I'm facing here is that even though I've defined -chop 0x0 for desktop its not skipping the chop for desktop instead it's chopping 43px for desktop just like on the mobile.

If you don't want the chop applied to some images, put the ones you do want chopped in parentheses and just chop them:
convert NoChop.png \( ChopMe.png ChopMeToo.png -chop 10x10 \) ...
Or, load the ones you want chopped first, chop them, then add the ones you don't want chopped:
convert ChopMe.png ChopMeToo.png -chop 10x10 NoChop.png ...

#!/bin/sh
desktop_path=./screenshots/desktop/
mobile_path=./screenshots/mobile/
mobile_cropped_path=./screenshots/mobile/cropped/
pdf_path=./pdf/
mogrify -path ${mobile_cropped_path} -chop 0x43 ${mobile_path}*.png
convert ${desktop_path}*.png ${mobile_cropped_path}*.png ${pdf_path}packets-temp.pdf

Related

Imagemagick - Getting the usable dimension of an image

I've a process which is creating a file with convert (ImageMagick) based on some parameter, and after that it checks the file and gives back the biggest dimension of it which has real pixels.
The commands look like this:
convert -size 5000x5000 xc:white -font {font} -pointsize {size} -fill black -draw "{some_occassional_additional_parameter}text 200,2500 \"{text}\"" {some_other_occassional_additional_parameter}{temporary_file}
convert {temporary_file}.png -trim +repage -format "%[w]x%[h]\n" info:
. It'll result something like: 526x425
This process runs half a million time per day, and it seems to be a huge bottleneck. I'm looking for a solution which can done this in memory, so not always creating a file and check it, but do it in memory somehow.
If can speed it up just like 50%, that'd be a huge achievement.
Thank You
Not at a computer to test, but change your first command to:
convert -size ... xc:... occasionalstuff -format "%#" info:
Note that you can, and probably should double quote the "%#" especially if you use expressions containing characters of significance to the shell, though it is not strictly necessary in this specific case.

ImageMagick: Split image into two with 55% of original image each

I want to split some images by percentage using ImageMagick.
To be more precise, I want to split an image into two images. The output-image of the left side should be 55% of the left side of the original image, the output-image of the right side should be 55% of the right ride of the original image.
(In case I am not making myself clear: The point is that there is sometimes important information in the middle of the images and this information would be cut off if we split the images exactly in the middle.)
What I have so far is this: mogrify -crop 55%x100% +repage -path ./cropped *.jpg
So at the moment, I am splitting the image into two and saving it in the "cropped"-folder. BUT, only the left side is 55% of the left side of the original image, the right side is 45% of the right side of the original image.
As this is my first time working with ImageMagick, I would really appreciate your help!
Here is another approach to splitting an image to create two output images that are 55% from the left and 55% from the right of the original...
convert input.png -set filename:0 "%[t]" \
\( +clone -roll +55+0% \) -extent 55x100% "%[filename:0]_%d.png"
That starts by setting a file name variable to use for the output. Then it makes a clone of the input image, and rolls it 55% to the right. The result is moving the rightmost 55% of the image out of the frame to the right and back into the frame on the left. Then after the parentheses a simple -extent operation keeps the leftmost 55% of each image. The output files are named from the input file with a "_0" or "_1" added.
As fmw42 suggested, you can make a loop command to run on multiple inputs, and include the path names in the command for your output files.
I think you would have to run a script loop over each image and use convert rather than mogrify. Mogrify can only output one image for each input image. You do not say what platform/OS or what version of ImageMagick. The following assumes Unix-like system with IM 6 and is one way to do that.
infile="original_file.suffix"
convert "$infile" -set filename:fname "%t" -write mpr:img +delete \
\( mpr:img -gravity west -crop 55x100%+0+0 +repage +write "path_to/cropped/%[filename]_0.suffix" \) \
\( mpr:img -gravity east -crop 55x100%+0+0 +repage +write "path_to/cropped/%[filename]_1.suffix" \) \
null:
Or, you could just run mogrify twice. Once for the left side and once for the right side. Use -gravity to control which as in the convert command.

Convert image from one format to another sent to STDOUT

I'd like to convert an image from .jpg to .png. This works just fine:
convert input.jpg output.png
But, I'm trying to have my output go to STDOUT instead of a file, which the manual says to use "-".
I tried using:
convert input.jpg -.png
But it just creates a file called -.png.
Is it possible to convert an image from one format to another and have it go to STDOUT?
Yes, just use a command like this to convert a JPEG to a PNG on stdout:
magick input.jpg PNG:-
These specifiers work on input as well as output. So, if you have a TIFF on stdin and want a 32-bit RGBA PNG on stdout:
magick TIFF:- PNG32:-
You often need these specifiers to ensure a specific filetype when it is not explicitly given, or you want to use a different extension. So, say you have some CCD device that produces RGB data in a raw binary file called image.bin and you want ImageMagick to read it. You can tell ImageMagick the format without having to change the filename (to image.rgb) like this:
magick -size WxH RGB:image.bin result.png
The possible formats are documented here.
The king of all of these formats is MIFF which is guaranteed to be able to hold any and all things you might throw at it, including floating-point values, transparency, masks, concatenated streams... so if you need a format to pass between ImageMagick commands, MIFF is a good option. An example, just to demonstrate because it is not optimal, might to be to concatenate two images from 2 separate ImageMagick commands into a third command that makes an animated GIF:
{ magick -size 100x60 xc:red miff:- ; magick -size 100x60 xc:blue miff:- ; } | magick -delay 80 miff:- result.gif

ImageMagick removes colors when alpha is 0 (png)

I am converting many 3D textures with imagemagick for a video game. My source files are png, my target files are png, too. But I notice that whenever the alpha channel drops to 0.0 my color information are gone (and I need them). I just want to scale all channels as they are. I guess there is a small switch that fixes that problem, but the deadline is near and I cannot find anything about that.
Simple command to reproduce this:
convert source-with-alpha.png -scale 2014 target.png (I also tried -resize and it also didn't work).
Doing just convert source-with-alpha.png target.png works fine though (but has no scaledown).
Thank you for your help.
I guess ImageMagick is trying to optimise something but not sure what/why. Maybe the idea is that if something is transparent you can't see it, so we might as well make it black so it compresses well.
Anyway, try separating the channels so they are all just treated as independent channels, then resizing and recombining:
convert input.png -channel RGBA -separate -resize XxY -combine result.png
I am not sure I understand your problem. I have no issue resizing a transparent PNG image with ImageMagick 6.9.10.28 Q16 Mac OSX with libpng 1.6.36. Perhaps you need to upgrade one or both.
Image:
Make white into transparent:
convert logo.png -transparent white logot.png
Resize it:
convert logot.png -resize 25% logot_small.png
I tried Mark Setchell answer with two different versions of Windows imagemagick but I still have this issue.
RGB becomes 0 if alpha is 0 when resizing.
A workaround was to add alpha a little bit so it becomes non-zero:
magic.exe input.tga -channel a -evaluate add 0.2% -channel RGBA -separate -filter Quadratic -resize -resize XxY! -combine result.tga
or also (same result)
magick.exe ( input.tga -alpha off -filter Quadratic -resize XxY! ) ( input.tga -filter Quadratic -resize XxY! -alpha extract -evaluate add 0.2% ) -compose Copy_Alpha -composite result.tga
("-filter Quadratic" is optional)
Post one of your tga files so we can test with it. What is your ImageMagick version? There should be no need for any switch. This works fine for me on IM 6.9.10.65 Q16 Mac OSX.
Make a transparent TGA:
convert logo: -transparent white logo.tga
transparent tga image
Resize by 50%
convert logo.tga -resize 50% logo2.tga
resized transparent tga image

Rotate individual letters of the same word in ImageMagick

I'm generating CAPTCHAs for training data and I have a pretty good ImageMagick script going already.
However, one thing I really want is for individual letters of the word to be slightly rotated, see for example this reCAPTCHA:
Is there an easy (or hard) way to accomplish this effect?
I think you need this:
#!/bin/bash
word="theId"
for (( i=0 ; i<${#word} ; i++ )) ; do
rotation=$(((RANDOM%10)*4)) # Generate random rotation for each letter
convert -background none -virtual-pixel none -pointsize 72 label:"${word:i:1}" +distort SRT $rotation miff:-
done | convert -background none - +append result.png
Basically I am creating and rotating one letter at a time and writing them to a MIFF stream, one after the other, and at the end, I am using +append to join together everything I see on the input stream.
If you want to scrunch the letters closer together (TM) you can add -trim +repage just before miff:-

Resources