Convert SVG file to multiple different size PNG files - image

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.).

Related

AppleScript + QuickTime — batch trim + create edit + export video

I'm looking for some help.
What I'm trying to do is to have AppleScript open a folder of videos, then get QuickTime to randomly trim them (as in the start frame from where it trims) and then have a variable length of the trim itself (say random between 1sec to 2sec as boundaries for the new 'clip'). After trimming and creating the new 'edit' (it would add this new random trimming to all the videos in the folder then add to timeline). QT then needs to export the edit to a new folder.
In summary, trying to make a quick auto-editing app that can just pick random selects from a folder full of videos then save an edit to a new video.
ANY help with this would be hugely appreciated!
I've been trying but to nail avail (I'm fairly new to coding to going around in circles).
Thanks!
Dylan
Like #CJK, I would recommend you use bash and ffmpeg as they are both available on macOS and both better known and more widely applicable than Applescript and QuickTime.
IMHO, as Apple does not ship a package manager, you would be well advised to use homebrew to install, update and remove packages. It is available on the homebrew website.
Once you have that, you can find any package you want with:
brew search packageXYZ
So, you can now install ffmpeg with:
brew install ffmpeg
Now you would want a bash script that:
loops through all your ".mov" files in a directory
gets their lengths
calculates a random duration
calculates a random start time
extracts that piece of video as a clip
and, finally at the end, assembles all the clips together
That will look something like this, which I would suggest you save in a bash script called $HOME/RandomClips
#!/bin/bash
# Set up globbing
shopt -s nullglob nocaseglob
# Clear list of files we are going to concatenate
> list.txt
N=1
# Loop through all ".MOV" files
for f in *.MOV ; do
# Tell user which one we are processing
echo Processing file $f
# Get length of this video in seconds
duration=$(mdls -raw -name kMDItemDurationSeconds "$f")
echo ... Duration: $duration
# Generate a random clip length less than 5 seconds
((seconds=RANDOM%5))
echo ... Clip length: $seconds
# Generate start time
((start=RANDOM%(duration-seconds)))
echo ... Start time: $start
# Extract clip into file called "Clip-1.mov", "Clip-2.mov" etc
clipname="Clip-$N.mov"
echo ... Extracting $clipname
ffmpeg -hide_banner -ss $start -i "$f" -t $seconds -pix_fmt yuv420p "$clipname"
# Add name of this clip to the list of files to concatenate at the end
echo "file $clipname" >> list.txt
# Increment clip counter
((N=N+1))
done
# Now join together all the extracted clips into a single file
ffmpeg -hide_banner -f concat -i list.txt -c copy -pix_fmt yuv420p mergedVideo.mov
Now you need to make that executable, just necessary once, with:
chmod +x $HOME/RandomClips
Then use cd to navigate to a directory of movies:
cd some/place/with/movies
and run the script with:
$HOME/RandomClips
The script is not the most robust or well-tested in the entire world but it should be 90+% good. You may have to resize videos to a fixed size so they all match formats. Likewise with codecs. Probably ask another question if that becomes an issue.
No-one said answers have to be 100% perfect, and as no-one else has suggested anything, this will hopefully get you well on your way.
If you want to debug the script, you can:
read the debug output line by line
check all the extracted clips look correct, i.e, "Clip-1.mov", "Clip-2.mov"
read the file called "list.txt" to see if it contains all the clips

Unix: Combine PDF -files and images into PDF -file?

My friend is asking this question, he is using Mac and cannot get PdfLatex working (having no dev CD, related here). Anyway my first idea:
$ pdftk 1.pdf 2.pdf 3.pdf cat output 123.pdf [only pdfs]
$ convert 1.png 2.png myfile.pdf [only images]
Now I don't know without LaTex or iPad's Notes Plus how to combine images and PDF -files. So how can I combine pdf -files and images in Unix?
You could run a loop, identifying PDF and images, and converting images to PDF with ImageMagick. When you're done, you assemble it all with pdftk.
This is a Bash-only script.
#!/bin/bash
# Convert arguments into list
N=0
for file in $*; do
files[$N]=$file
N=$[ $N + 1 ]
done
# Last element of list is our destination filename
N=$[ $N - 1 ]
LAST=$files[$N]
unset files[$N]
N=$[ $N - 1 ]
# Check all files in the input array, converting image types
T=0
for i in $( seq 0 $N ); do
file=${files[$i]}
case ${file##*.} in
jpg|png|gif|tif)
temp="tmpfile.$T.pdf"
convert $file $temp
tmp[$T]=$temp
uses[$i]=$temp
T=$[ $T + 1 ]
# Or also: tmp=("${tmp[#]}" "$temp")
;;
pdf)
uses[$i]=$file
;;
esac
done
# Now assemble PDF files
pdftk ${uses[#]} cat output $LAST
# Destroy all temporary file names. Disabled because you never know :-)
echo "I would remove ${tmp[#]}"
# rm ${tmp[#]}
I am gathering here some info.
Unix Commandline
More about Pdftk here.
Merging png images into one pdf file
Combine all files in a folder as pdf
Mac
Because the moderator in Apple SE removed the useful thread "Merge PDF files and images to single PDF file in Mac?"
here
-- I collect the tips here for Mac -- sorry but the moderator is very intolerant about collecting Newbie -things.
https://apple.stackexchange.com/questions/16226/what-software-is-available-preferably-free-to-create-and-edit-pdf-files-on-mac
https://apple.stackexchange.com/questions/812/how-can-i-combine-two-pdfs-in-preview
https://apple.stackexchange.com/questions/11163/how-do-i-combine-two-or-more-images-to-get-a-single-pdf-file
https://apple.stackexchange.com/questions/69659/ipad-pdf-software-to-edit-merge-annotate-etc-well-pdf-documents-like-in-deskto

Automatic resizing for 'non-retina' image versions

I'm looking for a solution that can save me from maintaining two versions of the same image, one for Retina displays (aka #2x), one another for non-Retina displays. My goal is to maintain the "2x" images only, and have some 'magic tool' resize all of them with a single click or even better upon building in XCode. Like "set it and forget it".
Can you help me? Thanks in advance.
If you just want to downscale them, you can have Xcode automatically generate all non-retina images during the build process. This example script uses "sips" because that is preinstalled on Macs.
The Script
#!/bin/bash
# Downsamples all retina ...#2x.png images.
echo "Downsampling retina images..."
dir=$(pwd)
find "$dir" -name "*#2x.png" | while read image; do
outfile=$(dirname "$image")/$(basename "$image" #2x.png).png
if [ "$image" -nt "$outfile" ]; then
basename "$outfile"
width=$(sips -g "pixelWidth" "$image" | awk 'FNR>1 {print $2}')
height=$(sips -g "pixelHeight" "$image" | awk 'FNR>1 {print $2}')
sips -z $(($height / 2)) $(($width / 2)) "$image" --out "$outfile"
test "$outfile" -nt "$image" || exit 1
fi
done
Automatic Execution
Create a new "Aggregate Target", name it "Downsample images".
Add a "Run script" phase to this target that runs the script.
Add the "Downsample images" target as a "Target Dependency" in your app target(s).
Notes
Remember to still add your 1x images to the Xcode project. Depending on your needs you might also want to:
exclude certain files from conversion
add the generated files to your .gitignore file
use ImageMagick's "convert" instead of "sips". (sips seems to fail for some indexed PNGs.)
run optipng
ImageMagick comes with a "compare" command if you want to check the downsampled versions.
This is quite an old thread, but I stumbled onto it, so I can elaborate on maintaining more than one size automatically.
Performance-wise, I'm not sure using the automatic downscaling is a wise idea, as it has to be done in real-time, but it should work on simpler cases.
Now, to convert these #2ximages automatically, a simple bash script should do the trick. l4u's solution works, but for guys with simpler needs who do not want to install guard, this also works (you still need to install ImageMagick, though) :
for f in $(find . -name '*#2x.png'); do
echo "Converting $f..."
convert "$f" -resize '50%' "$(dirname $f)/$(basename -s '#2x.png' $f).png"
done
It's trivial:
Only include #2x images in your project.
Make sure those images have the #2x suffix.
The system will automatically downscale for non-retina devices.
The only exception is if you are doing manual, low level Core Graphics drawing. You need to adjust the scale if so. 99.9% though, you don't have to worry about this.
u can simply use only *#2x.png images for your app.
but you must set the content mode = UIViewContentModeAspectfit for the imageviews,
then it will automatically fix the image to the releventimageviews.
Or what you can also do is: Have only the #2x images in your app's bundle then on the first launch. Take all the #2x photos and downsize them by 1/2 and store them in the documents directory. Then when you need your photos for a UIImageView say, just grab them for the documents directory and set it to your UIImageView using code and not Interface Builder!
I was wondering this a few weeks ago too and I realized that this is pretty much the only way to really do what you are looking for!
I've created http://l4u.github.com/blog/2012/04/02/resizing-retina-images-with-guard-for-cocos2d-iphone-slash-cocos2d-x/ to generate non-hd images on the fly when -hd images are created/updated. It uses guard, guard-shell and imagemagick
You can replace -hd with #2x.
Try Resource Helper on the Mac App Store
http://itunes.apple.com/us/app/resourcehelper/id521474600
It costs $10.49 but it's worth it. Checks if your images are Retina friendly (i.e. even numbered width/height dimensions) and generates the corresponding image inline. Also handles creation of ~ipad and #2x~ipad graphics as needed.
EDIT: I am not affiliated with the authors of Resource Helper.
What I've been doing for our applications is asking our designer to export everything twice as big as it needs to be, then running a little node script to resize the images (anything named #2x in the directory where you run the script). Presently, we're just running the script when every time we deploy (it's idempotent), but it could easily be incorporated into forever -w or some other file-change-watching library like guard.
Old thread, but I found a use for #nschum's script - I noticed though that it doesn't round numbers for the #1x images if it's dividing an odd number. If I recall correctly this introduces a performance hit; wound up slightly revising it as below. Alters the awk call slightly to do the division there and round it accordingly, and won't re-create #1x images if one already exists (you might want to remove that, dunno).
At this point we've pretty much hit the point where non-retina isn't a big deal (the iPad 2 is all that remains...? The original Mini too, I guess), so meh. Throwing it up for posterity.
#!/bin/bash
# Downsamples all retina ...#2x.png images.
dir=$(pwd)
echo "Downsampling Retina images..."
find "$dir" -name "*#2x.png" | while read image; do
outfile=$(dirname "$image")/$(basename "$image" #2x.png).png
if [ "$image" -nt "$outfile" ] && [ ! -f "$outfile" ]; then
if [[ $(dirname "$image") =~ "Images.xcassets" ]]; then
echo "Skipping Image XCode Assets directory"
else
basename "$outfile"
width=$(sips -g "pixelWidth" "$image" | awk 'FNR>1 {printf "%.0f\n", $2/2}')
height=$(sips -g "pixelHeight" "$image" | awk 'FNR>1 {printf "%.0f\n", $2/2}')
sips -z "$height" "$width" "$image" --out "$outfile"
test "$outfile" -nt "$image" || exit 1
fi
fi
done
echo "Finished downsampling Retina images"

imagemagick font metrics -- how to place a text in a grid?

let's have a look at the following image:
I have a horizontal grid and i want to place a text in this grid. The above example is wrong, because what i would like to have is that each character is placed exactly in one of the cells of the grid.
I wonder, if i can adjust the text-output in imagemagick to achieve this, without having to place each of the characters with it's own command.
Some additional facts:
i am using imagemagick from some shell script
i am doing rather complex drawings with imagemagick's MVG -- so it would be nice if the text could be still placed with the MVG commands
i am able to adjust the width of the grid by a few pixel, if this would be required with your solution, but all cells of course need to have the same width
i am always using the same fixed-width font (Courier) for this
i am able parse the font-metrics in my shell script and use this information to apply values to my text-commands
i only care about horizontal placement, vertical placement is not important because i render each row individual
With all this in mind -- is there any solution for my problem?
Thanks a lot!
You can use the kerning option - setting inter-character spacing.
e.g.
for i in 0 3 6 9 12 15
do
convert -kerning $i -font Courier -pointsize 24 label:":Kerning $i:" label_$i.jpg
done
will generate the following images. You must simply find the right kerning value for match the grid. (for monospaced font - like your Courier)
If you have a non mono-typed font that you want to force into a grid, you can use this script:
#!/usr/bin/env bash
rm test*png
font=~/Library/Fonts/WittenbergerFrakturMTStd.otf
gridsize=32x32
chr() {
case "$1" in
64 ) echo '\#' ;;
92 ) echo '\\' ;;
* ) printf \\$(printf '%03o' $1)
esac
}
for i in {32..127}; do
c=$( chr $i )
echo -n "$c: "
convert -background transparent -density 90 -pointsize 12 -gravity center -font "$font" label:"$c" -extent $gridsize test-$i.png
done
convert test-{32..127}.png +append test.png

Shell script for adjusting image size

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.

Resources