I am trying to automate the converting images to specified tif formats. I have it converting just fine, but am also needing to add "_GS" at the end of the file name and before the extension to each file converted. Below is what I have but have had no luck finding a solution to add "_GS" to the file name. Thanks in advance for any help.
for f in "$#"
do
echo "$f"
/usr/local/bin/mogrify -density 300 -resize 1000x1000 -type grayscale -define tiff:endian=msb -compress LZW -format tif "$f" [0]
done
Item 1: With Image Magick, to create a new file instead of overwriting an existing one, use convert, not mogrify (magick convert with newer versions of IM).
Item 2: You can use shell parameter expansion to remove the extension, and then build the new filename from that and the new suffix:
for f in "$#"
do
echo "$f"
/usr/local/bin/convert "$f" -density 300 -resize 1000x1000 -type grayscale \
-define tiff:endian=msb -compress LZW -format tif "${f%.*}_GS.tiff"
done
${variable%pattern} returns the expansion of variable with the shortest match of pattern removed from the end.
Related
I have the magick absolute in a folder and in a sub-folder temp I have images. I need/want to process the images and write them to another sub-folder output.
folder (with magick)
temp sub-folder (with input files)
output sub-folder (where processed images are placed)
But I am unable to stop the variable i picking up the path temp/. How do I stop it? Do I have to strip the characters temp/ from i then use it? Or is there a simple way to do this?
for i in temp/*; do
./magick convert -resize 450 -strip -quality 90% temp/$i output/$i
done
Yes you can with parameter expansion:
shopt -s nullglob
for i in temp/*; do
./magick convert -resize 450 -strip -quality 90% "$i" "output/${i#temp/}"
done
The nullglob prevents 0 matches from expanding to the pattern.
Maybe you can also just change working directory to temp and use ... I'm just not sure if magick will still work if referred from a different directory.
cd temp || exit
for i in *; do
../magick convert -resize 450 -strip -quality 90% "$i" "../output/$i"
done
I managed (with the help of SO) to make perfect png-snippets from a pdf file with graphicsmagick. My pdf contains text and formula each "snippet" on a single page. My command trims the content of a page to the very content and finally scales this up to 2000 pixel width.
Untill now, I need to repeat that command for each single page in every pdf. I am wondering how to automate this. I think I could try a loop for the repetition of the command for every page i untill the last page.
Assume file1.pdf is in my current working directory.
gm convert -density 300x300 file1.pdf[0] -trim -resize 2000x file1_page1.png
gm convert -density 300x300 file1.pdf[1] -trim -resize 2000x file1_page2.png
gm convert -density 300x300 file1.pdf[2] -trim -resize 2000x file1_page3.png
...
How can I set a counter and run a loop for every page in my document?
You are in luck. GraphicsMagick knows how to do that for you:
gm convert -density 300x300 input.pdf -trim -resize 2000x +adjoin output-%d.png
If you are ok using ImageMagick instead, you can set the starting output file number to 1 instead of 0 and don't need the -adjoin:
convert -density 300x300 input.pdf -scene 1 -trim -resize 2000x output-%d.png
Or, if you want them all done in parallel, use GNU Parallel:
parallel gm convert -density 300x300 {} -trim -resize 2000x output-{#}.png ::: $(identify input.pdf | awk '{print $1}')
for file in *.pdf
do
pages=$(identify "$file" | wc -l)
for (( i=0; i<$pages; i++ ))
do
name=$(sed "s/\.pdf$/$i.png/g" <<< "$file");
gm convert -density 300x300 "$file[$i]" -trim -resize 2000x "$name"
done
done
Try this one.
It will convert every page in every *.pdf file to .png.
I am trying to convert an entire folder to grayscale, using image magick.
convert *.jpg -colorspace Gray -separate -average
is met with this error :
convert: `-average' # error/convert.c/ConvertImageCommand/3290.
What is the correct command for this?
If you have lots of files to process, use mogrify:
magick mogrify -colorspace gray *.jpg
If you have tens of thousands of images and a multi-core CPU, you can get them all done in parallel with GNU Parallel:
parallel -X magick mogrify -colorspace gray ::: *.jpg
Also, the following can be used in a script - for the context menu of file managers like Dolphin, Nautilus, Nemo, Thunar etc:
for filename in "${#}"; do
name="${filename%.*}"
ext="${filename##*.}"
cp "$filename" "$name"-grayscale."$ext"
mogrify -colorspace gray "$name"-grayscale."$ext"
rm "$name"-grayscale."$ext"~
done
In here I found a piece of code that finds and resizes all images within a folder with applescript
Now I need to apply a stamp to those images one by one. I already have a transparent jpg prepared with the same size and ready to be pasted on all of them.
I just lack the knowledge to do it on terminal so I could mix it with applescript.
Does anyone know how to do this without making a workflow? Because it takes a lot of time and keeps the laptop busy
Updated Again :-)
You can get the height of an image like this:
identify -format "%h" image.jpg
500
and the width like this:
identify -format "%w" image.jpg
800
If you want to find the lesser of the height and the width, and then take 10% of that for your logo size and make it integer, you would do:
identify -format "%[fx:int(0.1*min(h,w))]" image.jpg
50
If you want to put that in a variable, you would do
logosize=$(identify -format "%[fx:int(0.1*min(h,w))]" image.jpg)
echo $logosize
50
You could then use that in the original command below like this:
convert image.jpg -gravity southeast \
\( copyright.png -resize "${logosize}x${logosize} \) \
-composite result.jpg
I suspect you are going to want to run that with the find command, aren't you? :-)
find . -iname \*.jpg -exec bash -c 'echo Processing {};logosize=$(identify -format "%[fx:int(0.1*min(h,w))]" "{}"); echo $logosize;convert "{}" -gravity southeast \( copyright.png -resize "$logosizex$logosize" \) -composite "{}"' \;
Updated Answer
If you want to resize your original image before compositing the logo unchanged on top, use a command like this:
convert image.jpg -resize 2000x1000 -gravity southeast copyright.png -composite result.jpg
If you want to resize the logo before compositing it on top of the unchanged original image, use a command like this:
convert image.jpg -gravity southeast \( copyright.png -resize 700x200! \) -composite result.jpg
Original Answer
I would use ImageMagick. It is extremely powerful and simple to install if you use homebrew. Ask if you don't know how...
Let's assume you have an image called image.jpg and a transparent logo/copyright called copyright.png.
image.jpg
copyright.png
Then the command to do a single image would be:
convert image.jpg copyright.png -composite result.jpg
If your logo/copyright and image are different sizes, and you want to force the logo to, say, the bottom right corner, just set the -gravity accordingly like this:
convert image.jpg -gravity southeast copyright.png -composite result.jpg
If you wanted to do all the JPEGs in the folder, you would need a loop:
#!/bin/bash
shopt -s nullglob
shopt -s nocaseglob
for f in *.jpg; do
convert "$f" copyright.png -composite "$f"
done
By the way, you cannot have a transparent JPEG - that format doesn't support transparency.
If you are really intent on using Applescript - I don't know why anyone would be - you can call the above using do shell script - make the file executable first. Ask if unsure how.
If you want to recurse down into all directories (folders) starting at the one you are currently located in and add the logo/copyright to all images, I would make a copy of them somewhere else first and do a trial run. The command would be:
find . -iname "*.jpg" -exec convert "{}" copyright.png -composite "{}" \;
That says... "find, starting at the current directory (.), disregarding upper/lower case (-iname), all files ending in "JPG", and apply the logo/copyright to them, resaving on top of the original file".
I had same issue years ago, and the only way I found is an Applescript using Photoshop (duplicate layer containing the logo on the photo and flatten file).
the script loops to all file of a folder.
... but you need Photoshop for this script !
I can share that script if it helps
I'm on Ubuntu, and I have a tree of folders containing .pdf files. I need to convert each one to a .png format. The bash script I am currently using is:
for f in $(find ./polkadots -name 'image.pdf'); do
convert -transparent white -fuzz 10% $f image.png;
done
I have tested the for loop by itself, and it works (it produces a list of all the .pdf files under the ./polkadots folder that I need to convert):
for f in $(find ./polkadots -name 'image.pdf'); do
echo "$f";
done
I have tested the imagemagic convert command by itself, and it works (it converts a single file in my current directory from .pdf to .png):
convert -transparent white -fuzz 10% image.pdf image.png
However, when I combine them... the console sits and thinks for a while, and then concludes.. but no files have been created or changed, and no error messages are produced. What am I doing wrong?
EDIT: The new .png files are being created, but they are being created in my current directory, instead of in the sub-directory where the .pdf was found. How do I fix this?
Try using find alone. No need to use a loop.
I haven't tested this command but it should work.
find ./polkadots -name 'image.pdf' -exec convert -transparent white -fuzz 10% {} image.png \; -print
The -print at the end is optional. I prefer to see which files have been modified.
Maybe you can find output option in convert command directly, which can export the png file to your expect folder. Anyway follow your idea, here is the updated code:
find ./polkadots -type f -name "image.pdf" |while read line
do
dir=${line%/*}
convert -transparent white -fuzz 10% $line image.png
mv image.png ${dir}/image.png
done
If you need convert all pdf files under polkadots folder, try this:
find ./polkadots -type f -name "*.pdf" |while read line
do
dir=${line%/*}
file=${line##*/}
file=${file%.*}
convert -transparent white -fuzz 10% $line ${file}.png
echo mv ${file}.png ${dir}/${file}.png
done
If you are using bash 4+, you should use globstar instead of find
#!/bin/bash
shopt -s globstar
for f in ./polkadots/**/image.pdf; do
convert -transparent white -fuzz 10% "$f" "${f%/*}/image.png"
done
If you're using an older bash, your original answer is close to fine, but has a few bugs/potential bugs,
If you directories have spaces in them, your original script will case errors, so use the | while read -r -d '' f syntax.
Don't put a ; at the end of command lines
Quote all variables to prevent expansion problems
As you pointed out, main issue in your case was not specifying destination dir, so you can use ${f%/*} parameter expansion to get the dir (this will delete everything including and after the last / in $f, then put the / back and append the filename like below.
Edited
#!/bin/bash
find ./polkadots -name "image.pdf" -print0 | while read -r -d '' f; do
convert -transparent white -fuzz 10% "$f" "${f%/*}/image.png"
done