Is there a way to adjust all image sizes in a directory?
If I set the max size to 800x600 it will make larger ones smaller and leave smaller ones at their original size.
for img in *.png; do
convert "$img" "800x600>" $(basename "$img" .png)_new.png
done
convert is from ImageMagick. ">" says it's only resized if larger. See here for its other options.
image magick package needs to be installed:
mogrify -resize 320x240 *.jpg
where 320 = width, 240 = height
or you can just leave width parameter:
mogrify -resize 320 *.jpg
and rest will be taken care of.
Various packages exist for command line or script driven manipulation of image files.
I'd suggest looking at netpbm, or ImageMagick. Personally I prefer the former as it's far simpler to use.
Related
To create an image thumbnail using an older version of ImageMagick, it was possible in the following ways:
(To aid in futher referencing, examples are numbered.)
1. convert.exe image.jpg -thumbnail 100x100 ./converted/converted_image.jpg
2. mogrify.exe -thumbnail 100x100 -path ./converted image.png
Now I have ImageMagick 7 (downloaded just yesterday), and during installation I intentionally turned "Install legacy utilities (e.g. convert.exe)" checkbox off. That is, I have only one utility in my ImageMagick directory: magick.exe.
I'm trying to understand what is the correct and future-proof way to perform above-mentioned operations according to modern ImageMagick versions.
A quote from https://imagemagick.org/script/porting.php#cli:
animate, compare, composite, conjure, convert, display, identify, import, mogrify, montage, stream
To reduce the footprint of the command-line utilities, these utilities are symbolic links to the magick utility. You can also invoke them from the magick utility, for example, use magick convert logo: logo.png to invoke the magick utility.
In the same source:
With the IMv7 parser, activated by the magick utility, settings are applied to each image in memory in turn (if any). While an option: only need to be applied once globally. Using the other utilities directly, or as an argument to the magick CLI (e.g. magick convert) utilizes the legacy parser.
Hmm...
Works:
3. magick.exe convert image.jpg -thumbnail 100x100 ./converted/converted_image.jpg
4. magick.exe mogrify -thumbnail 100x100 -path ./converted image.png
Still works (the same way as magick.exe convert):
5. magick.exe image.jpg -thumbnail 100x100 ./converted/converted_image.jpg
However, the following one doesn't work (expected: should work the same way as magick.exe mogrify):
6. magick.exe -thumbnail 100x100 -path ./converted image.png
My question is: Which syntax should I use for convert and for mogrify? 3 and 4, or 4 and 5, or something different?
AFAIK, and I am happy to add any corrections suggested, it works like this.
The first idea is that you should use version 7 if possible and all the old v6 commands, WITH THE EXCEPTION OF convert should be prefixed with magick. That means you should use these
magick ... # in place of `convert`
magick identify ... # in place of `identify`
magick mogrify ... # in place of `mogrify`
magick compare ... # in place of `compare`
magick compose ... # in place of `compose`
If you use magick convert you will get old v6 behaviour, so you want to avoid that!
Furthermore, v7 is more picky about the ordering. You must specify the image you want something done to before doing it. That means old v6 commands like:
convert -trim -resize 80% input.jpg output.jpg
must now become:
magick input.jpg -trim -resize 80% output.jpg # magick INPUT operations OUTPUT
So, looking specifically at your numbered examples:
Should become:
magick image.jpg -thumbnail 100x100 ./converted/converted_image.jpg
Should become:
magick mogrify -thumbnail 100x100 -path ./converted image.png
invokes old v6 behaviour because you use magick convert instead of plain magick, and should be avoided
Is correct, modern syntax
Is correct, modern syntax
Looks like you meant magick mogrify because you didn't give input and output filenames and because you use -path, but it looks like you accidentally omitted mogrify. If you didn't accidentally omit mogrify, then you probably meant to use the old convert-style command, and need an input and an output file and you need to specify the input file before the -thumbnail.
Keywords: Usage, wrong, modern, v7 syntax, prime.
I have hundreds of jpgs of varying sizes (e.g. 2304px x 2323px).
In gimp I can use a batch filter to change these to certain sizes, relative or absolute. But for some configurations I have to do the following manually, which for all the images takes forever:
Change the size of the shortest side to 500px, maintaining the aspect ratio so the longer side is at least 500px. So if the image was 1000 x 1200, it will now be 500 x 600. The images come in both portrait and landscape.
Change the canvas size so the image is a 500px x 500px square, centered. This will cut off part of the image (which is fine, most images are almost square anyway).
Export the file with a -s appended to the file name.
Is there a script I can use to automate these steps?
Something like this in ImageMagick. It's not as hard as it looks as most of it is comment. Try to on a COPY of your files - it does all the JPEGs in the current directory.
#!/bin/bash
shopt -s nullglob
shopt -s nocaseglob
for f in *.jpg; do
echo Processing $f...
# Get width and height
read w h < <(convert "$f" -format "%w %h" info: )
echo Width: $w, Height: $h
# Determine new name, by stripping extension and adding "s"
new=${f%.*}
new="${new}-s.jpg"
echo New name: $new
# Determine lesser of width and height
if [ $w -lt $h ]; then
geom="500x"
else
geom="x500"
fi
convert "$f" -resize $geom -gravity center -crop 500x500+0+0! "$new"
done
Unless you find your way with gimp, you may want to look into ImageMagick: the mogrify tool allows to modify and resize images.
Beware: mogrify will overwrite your file, unless you use stdin/stdout. You probably want a script like this:
#!/bin/sh
for image in `ls /your/path/*jpg`; do
mogrify -resize ... - < "$image" > "${image%%.png}-s.jpg"
done
I am using ImageMagick to resize image resolution by using below command-line option
convert abc.png -set units PixelsPerInch -density 75 abc_a.png
I am in need of this: if any images has more than 300 width OR more than 100 height, I want to convert it to width 300 width and 100 height, with changing above dpi (i.e. 75dpi).
Can any one help me on this?
If you are on Linux/OSX, you can get the image dimensions like this:
identify -format "%w %h" input.jpg
So, if you want the width and height in variables w and h, do this:
read w h < <(identify -format "%w %h" input.jpg)
Now you can test the width and height and do further processing if necessary:
[ $w -gt 300 -o $h -gt 100 ] && convert input.jpg -set units ...
Or, if you want to be more verbose:
if [ $w -gt 300 -o $h -gt 100 ]; then
convert ...
fi
So, the total solution I am proposing looks like this:
#!/usr/bin/bash
read w h < <(identify -format "%w %h" input.jpg)
[ $w -gt 300 -o $h -gt 100 ] && convert input.jpg -set units ...
JPEG or PNG makes no difference, so just replace my JPG with PNG if that is the format of your choice.
Updated for Windows
Ok, no-one else is helping so I will get out my (very) rusty Windows skills. Get the image width something like this under Windows:
identify -format "%w" input.png > w.txt
set /p w=<w.txt
Now get the height:
identify -format "%h" input.png > h.txt
set /p h=<h.txt
You should now have the width and height of image input.png in 2 variables, w and h, check by typing
echo %w%
echo %h%
Now you need to do some IF statements:
if %w% LEQ 300 GOTO SKIP
if %h% LEQ 100 GOTO SKIP
convert ....
:SKIP
Note:: You may need ^ in front of the percent sign in Windows.
Note: You may need double # signs in scripts because Windows is illogical.
You cannot control the -density and the width plus height at the same time!
Density (or resolution), when creating an image, will automatically resize the image to a certain number of pixels in width and height (or it will have been ignored).
Density (or resolution), when displaying an image (like in a browser window, within a HTML page, or on a PDF page), will not change the original images dimensions: instead it will zoom in or zoom out the respective view on the image.
Density (or resolution), when used in the metadata of an image (which is not supported by every file format), does not change the image dimensions -- it just gives a hint to the displaying software, at what zoom level the image wants to be displayed (which is not supported by every image viewer).
Now to your question...
Try this command:
convert abc.png -scale 300x100\> abc_a.png
This will scale the image only if
either the original image's width is larger than 300 pixels,
or the original image's height is larger than 100 pixels.
The scaling will preserve the aspect ratio of the original image. -- Is this what you are looking for?
If the image is smaller, then no scaling will happen and abc_a.png will have the original dimensions.
If you want to *emphatically scale the image to 300x100, no matter what, and loose the aspect ratio, bearing with some distortion of the original image, the use:
convert abc.png -scale 300x100\! abc_b.png
(However, this will also scale smaller images...)
I have a folder of images over 4MB - let's call this folder dsc_big/. I'd like to use convert -define jpeg:extent=2MB to convert them to under 2MB and copy dsc_big/* to a folder dsc_small/ that already exists.
I tried convert dsc_big/* -define jpeg:extent=2MB dsc_small/ but that produces images called -0, -1, and so on.
What do I do?
convert is designed to handle a single input file as far as I can tell, although I have to admit I don't understand the output you're getting. mogrify is better suited for batch processing in the following style:
mogrify -path ../dsc_small -define jpeg:extent=2MB dsc_big/*
But honestly I consider it dangerous for general usage (it'll overwrite the original images if you forget that -path) so I always use convert coupled with a for loop for this:
for file in dsc_big/*; do convert $file -define jpeg:extent=2MB dsc_small/`basename $file`; done
The basename call isn't necessary if you're processing files in the current directory.
This was the command which helped me after a long try.
I wanted to make same sized thumbnails from a big list of large images which have variable width and height . It was for creating a gallery page.
convert -define jpeg:size=250x200 *.jpg -thumbnail 250x200^ -gravity center -extent 250x200 crop/thumbnail-%d.jpeg
I got re-sized thumbnails which all having same width and height. :) thanks to ImageMagick.
Here's a solution without using for loops on the console
convert *.jpeg -define jpeg:extent=2MB -set filename:f '../dsc_small/%t_small.%e' +adjoin '%[filename:f]'
Although this is an old question, but I'm adding this response for the benefit of anyone else that stumbles upon this.
I had the same exact issue, and being discouraged by the use of mogrify, I wrote a small Python based utility called easymagick to make this process easier while internally using the convert command.
Please note, this is still a work in progress. I'll appreciate any kind of feedback I can get.
I found that cd-ing into the desired folder, and then using the bash global variable $PWD made my convert not throw any errors. I'm utilizing ImageMagick's recently implemented caption: http://www.imagemagick.org/Usage/text/#caption function to label my images with the base filename and place them in another directory within the first.
cd ~/person/photos
mkdir labeled
for f in $PWD/*.JPG; do
width=$(identify -format %w $f)
filename=$(basename $f .JPG)
convert -background '#0008' -colorspace transparent -fill white -gravity center -size ${width}x100 caption:"${filename}" ${f} +swap -gravity south -composite "$PWD/labeled/${filename}.jpg";
done
This works for me
convert -rotate 90 *.png rotate/image.jpg
produces image-0.jpg, image-1.jpg, image-2.jpg ..... in the 'rotate' folder. Don't know of a way to preserve the original filenames though.
I have a logo image in SVG format and I am wondering if theres a way to generate multiple different sized png files.
Eg, I set 20 different width and height and it generates 20 PNG files. It okay if I have to do it 5 images at a time.
I have illustrator installed and cant figure out how to do this on it.
Thanks for all of your help!
The accepted answer is fine. There is an official help on options available.
Also basic Shell commands will do nicely here:
for x in 10 100 200 ; do inkscape --export-png logo${x}.png -w ${x} logo.svg ; done
On the command line in windows use this line from #avalancha in the comments
for %x in (100 200 300) ; do inkscape --export-png logo%x.png -w %x logo.svg ; done
I don't know about Illustrator, but this should be easy using the Inkscape command line options. For example, using Ruby:
$ ruby -e '[10,100,200].each { |x| `inkscape --export-png logo#{x}.png -w #{x} logo.svg` }'
Here's how to make it much faster (3x for me for just 5 exports on an SSD) by launching Inkscape just once, and how to export the images to different directories (as Android uses):
#!/bin/sh
# Converts the Inkscape icon file ic_launcher_web.svg to the launcher web & app png files.
PROJECT="My Project Name"
INPUT="source-assets/ic_launcher_web.svg"
MAIN="${PROJECT}/src/main/"
RES="${MAIN}res/"
DRAWABLE="${RES}/drawable"
inkscape --shell <<COMMANDS
--export-png "${MAIN}ic_launcher-web.png" -w 512 "${INPUT}"
--export-png "${DRAWABLE}-mdpi/ic_launcher.png" -w 48 "${INPUT}"
--export-png "${DRAWABLE}-hdpi/ic_launcher.png" -w 72 "${INPUT}"
--export-png "${DRAWABLE}-xhdpi/ic_launcher.png" -w 96 "${INPUT}"
--export-png "${DRAWABLE}-xxhdpi/ic_launcher.png" -w 144 "${INPUT}"
quit
COMMANDS
This is a bash shell script. On Windows you can run it in MINGW32 (e.g. GitHub's Git Shell) or convert it to a Windows DOS shell script. (For a DOS script, you'll have to change the "here document" COMMANDS into something DOS can handle. See heredoc for Windows batch? for techniques such as echoing multiple lines of text to a temp file.)
Take a look at inkmake. I actually made that tool just for batch exporting SVG files to PNG etc in different sizes. It was design because I wanted to save in Inkscape and then just run inkmake in a terminal and it will export all depending PNG files.
If you haven't already, install imagemagick. On OSX, that requires rsvg support specifically:
brew install imagemagick --with-librsvg
You also need inkscape, otherwise you may find that your images come out all black (except for transparent areas).
brew install homebrew/gui/inkscape
Then, you should be able to convert as follows:
convert -density 1536 -background none -resize 100x100 input.svg output-100.png
The 1536 is a workaround for something I'm not able to find good answers to. In my experiments, omitting the -density argument creates images that are terribly small. Converting an image to -size 100x100 at -density 1024 gives me an output image of 96x96, so what I'm doing instead is overshooting on the density and resizing down to the target size.
TL;DR use a density that is 1500 times larger than your target size, and go from there.
There are many ways to bulk-run that command. Here is one in the shell:
for s in 10 100 200 ; do convert -density 1536 -background none -resize ${s}x${s} input.svg output-${s}.png ; done
Based on zany's answer but updated to handle Inkscape 1.1 which requires the -o option for output filename and --export-type as opposed to --export-png to declare your export type.
for x in 10 100 200 ; do inkscape --export-type=png -o logo${x}.png -w ${x} logo.svg ; done
I created a tool to do exactly that. You can define which output sizes you want, and their folder structure. So it's as easy as just running it on your folder with svg files, and then png files are added to your project in correct folders.
https://github.com/Inrego/SvgToPng
I hope it's helpful.
I used the below command to create the icons for Angular PWA.
First "cd" into the inkscape installation folder before running the below command in windows command prompt.
for %x in (72 96 128 144 152 192 384 512) ; do inkscape --export-filename=C:\temp\icons\icon-%xx%x.png -w %x -h %x "{filePath}\{fileName}.svg"
On Ubuntu 20.04 with Inkscape 1.1.1 (eb90963e84, 2021-10-02) this generates 6 images with different resolutions (32x32, 64x64, etc) from icon.svg:
for x in 16 24 32 48 64 256 ; do inkscape --export-type="png" --export-filename=${x}x${x}.png -w ${x} -h ${x} icon.svg ; done
You can add or remove resolutions by adding elements (separated with spaces) right for x in <here> ;.
Remember this always will generate square images (same width and height).
Change icon.svg to your .svg file and to change the output filenames change --export-filename=<this> to the filename you want.
TIP: use ${x} to get the current resolution (32, 64, etc.).