Convert a bunch of images from svg to png - svg

I need to convert from svg to png all the images in a folder. Lets say that images are called test1.svg, test2.svg, ... , testn.svg. Using the following script:
for i in *.svg
do
convert "$i" PNG24:"$i".png
done
does the job correctly, and the images are called test1.svg.png, test2.svg.png, ... , testn.svg.png. My questions are:
1) Is it possible to make the output images be called test1.png, test2.png, ... , testn.png, essentially removing the 'svg' part from the name?
2) Is it possible to send them directly into some other directory?
Thanks!

Yes. You can make another directory and send them there like this:
mkdir other
for i in *.jpg; do
convert "$i" PNG24:other/"${i%jpg}png"
done
If you have lots of images to do, and you are on macOS or Linux, I would recommend GNU Parallel to get the job done faster:
mkdir other
parallel convert {} PNG24:other/{.}.png ::: *jpg

Related

bash - opening an image only when a corresponding text file exists

I came across a problem in Bash when I would try to only open images based upon the information stored in .txt files about them. I am trying to sort a number of images by size or height, and display an image with them in the sorted order, but if there exists a .jpg in the folder without a .txt file with the same name, it should not process it.
I have the sorting piece of my situation done, and am trying to figure out how I would go about opening only the images that have a .jpg extension WITH a .txt file.
I figured a solution would look like me putting every .jpg's name (without extension) in a list and then process through the list and run something like:
[if -f $filename.txt ]; then ~~~
but I came across the problem of iterating through without a for-loop, or else all the pictures would open multiple times. My attempt was:
for i in *jpg; do
y=$y ${i.jpg}
done
if[ -f $y.txt ] then
(sorting parts)
This only looked at the last filename in y, as it should, but I am trying to figure out a way to look at each separate filename and see if there exists that textfile, in order to include it in the sorting.
Thanks so much for your help!
Collecting a list of file names in a single variable is an antipattern. You want to collect them in an array instead.
a=()
for f in *.jpg; do
if [ -e "${f%.jpg}".txt ]; then
continue
fi
a+=("$f")
done
# now do things with "${a[#]}"
Frequently, you don't really need to collect the files in an array -- just do everything you were doing inside the for loop to each individual file as you traverse the files.
(And actually y=$y ${i%.jpg} doesn't append to y -- it sets y to itself for the duration of attempting to execute a file named i sans the .jpg extension, which would most likely fail in the vast majority of cases.)
I would do the file check first such that find just reports files that have a corresponding text file. The following snippet will just display jpg files that have a corresponding txt file:
find . -name "*.jpg" -maxdepth 1 -exec /bin/bash -c '[ -e "${0%.*}.txt" ] && echo "$0";' {} \;

Regarding comparison of 2 image sequences in Linux/Ubuntu

I have images in 2 different folders, 100 images in each of the 2 folders.The images belong to photographs taken from 2 different simulations.The 100 images are the 100 time steps of the 2 simulations.I wish to compare the images frame by frame. Can they be displayed on the screen with some software,such that I just need to press the arrow keys(up/down) and the images from the 2 sequences will BOTH move forward/backward by one step, so that I can compare the 2 images frame by frame simultaneously. I do not wish to mathematically subtract images, just compare them visually with the eyes.
Windows, I came to know has avisynth and pdplayer for the above. avxsynth is the Linux version of avisynth,but it is unstable in my computer.
This is the only question I found,before posting this and it is off-topic
How to list an image sequence in an efficient way? Numercial sequence comparison in Python
Can anyone please suggest any other option ?
Have you considered using ImageMagick, specifically montage, and a simple shell script to create a new set of images? (Where each new image consists of your two previous images glued (montaged) together side by side.)
ImageMagick will also support subtraction of images, which can be montaged into the new set too, should you change your mind about that.
Or the creation of animations where the images oscillate between your two runs so you can compare them more easily. (i.e. create a 3rd folder with 100 new images each of which is an animation alternating between the two runs.)
You may want to consider generating a little html with a shell-script, and putting each image or set of images into its own webpage along with forward and backward buttons. It's pretty trivial, and gives you a nice little web-browser slideshow. You can pick up the necessary HTML in a couple of minutes. You wouldn't need much more than the A HREF and IMG tags. Webbrowsers support local file:// URLs. (Again, a 3rd directory with 100 html files linking to images in the first 2 directories.)
Or you could generate one big webpage with all the images in it, and just scroll up and down...
I am new to shell scripting, can you please give me a shell script. I could not find out how to write the shell script. I could make use of montage. Suppose the 2 directories are dir1 and dir2, and each of them has five files file_001,file_002,file_003,file_004,file_005 can you please post the shell script ??
Sure. I happen to like TCSH (or CSH) for this, just for the :t option...
Note: montage output filename needs an extension to tell montage what the output graphics filetype is... (e.g. .jpeg or .gif or whatever...)
% mkdir dir3
% ls -a *
dir1:
./ ../ file_001 file_002 file_003 file_004 file_005
dir2:
./ ../ file_001 file_002 file_003 file_004 file_005
dir3:
./ ../
% foreach VAR ( dir1/file* )
montage -background #000000 -geometry +4+4 $VAR dir2/$VAR:t dir3/out_$VAR:t.jpeg
end
% ls d*
dir1:
./ ../ file_001 file_002 file_003 file_004 file_005
dir2:
./ ../ file_001 file_002 file_003 file_004 file_005
dir3:
./ out_file_001.jpeg out_file_003.jpeg out_file_005.jpeg
../ out_file_002.jpeg out_file_004.jpeg
Nothing to it... For HTML you could just echo text into a file...
% set Q = '"'
% mkdir dirfoo
% foreach VAR ( dir1/file* )
echo "<html><head></head><body><img src=${Q}../$VAR${Q}></img></body></html>" >> dirfoo/$VAR:t.html
end
That sort of thing...
Perhaps:
% foreach VAR ( dir1/file* )
echo "<html><head></head><body><table><tr><td><img src=${Q}../$VAR${Q}></img></td><td><img src=${Q}../dir2/$VAR:t${Q}></img></td></tr></table></body></html>" >> dirfoo/$VAR:t.html
end

Combining all the images in folder into a video

I have a script that takes tons of pictures and names them with a time-stamp. These Images are all put into one folder. I want to create a script that takes all the pictures in the folder, combines them into a 10fps video, saves this video as the date and time it started from to the time it ended, and deletes the original pictures. So far, I've seen some people use Ffmpeg or mencoder but I'm not sure how to use these or do what I want with them. Any help is appreciated! Thanks.
You can use the FFMpeg command line interface. You invoke it from the shell. Download the binary and run it by pointing it at the desired directory. %05d is simply string formatting for numbers. %05d just says pad with 4 leading zeros 0001.jpg or whatever.
# Create a directory and copy the original images there for manipulation:
mkdir temp
cp *.JPG temp/.
# Resize the images:
mogrify -resize 200x200 temp/*.JPG
# Create the morph images
convert temp/*.JPG -delay 10 -morph 5 temp/%05d.jpg
# Stitch them together into a video
ffmpeg -r 50 -qscale 2 -i temp/%05d.jpg output.mp4
from http://www.itforeveryone.co.uk/image-to-video.html

Bash - renaming multiple file extensions

I've just very recently switched to Linux and I want to change a load of files to have different extensions. For example I want to change .doc/docx to .txt and images to .jpg and so on. Is there a csh script that would cover any extension or would I have to write a new one for each filetype.
I have this so far, but I'm not sure if it will actually work. Any help is much appreciated!
#!/bin/bash
for f in *.$1
do
[ -f "$f" ] && mv -v "$f" "${f%$1}$2"
done
No need to reinvent the wheel:
http://linux.die.net/man/1/rename
rename .doc .txt *.doc
You need proper programs to convert file format:
Use wvWare to convert doc to html
Use ImageMagick to convert png to jpg
Use html2text to convert html to txt
That would do the rename; keep in mind that renaming a Word document won't cause it to become text, though.

Resize a list of images in line command

I would like to resize a list of images, all in the directory. To achieve that, I use convert from imagemagick. I would like to resize
image1.jpg
image2.jpg
...
into
image1-resized.jpg
image2-resized.jpg
...
I was wondering if there is a method to achieve this in a single command line. An elegant solution could be often useful, not only in this case.
EDIT:
I would like a non script-like solution, ie. without for loop.
If you want to resize them to 800x600:
for file in *.jpg; do convert -resize 800x600 -- "$file" "${file%%.jpg}-resized.jpg"; done
(works in bash)
ls *.jpg|sed -e 's/\..*//'|xargs -I X convert X.jpg whatever-options X-resized.jpg
You can eliminate the sed and be extension-generic if you're willing to accept a slightly different final filename, 'resized-image1.jpg' instead of 'image1-resized.jpg':
ls|xargs -I X convert X whatever-options resized-X
GNU Parallel is even easier than for loops, and it's often faster:
parallel convert -resize 800x600 -- "{}" "{.}-resized.jpg" ::: *.jpg
A few things going on here, from right to left:
::: *.jpg means run the command for every jpg file
{.} means insert the current filename without the suffix (.jpg)
{} means insert the current filename
parallel means run the following command many times in parallel. It will choose the max to do in parallel to match the number of cores your computer has. As each one finishes it will launch the next one until all the jpg files are converted.
This runs the command convert --resize 800x600 -- foo.jpg foo-resized.jpg for each file. The -- tells convert to stop processing flags, in case a file name happens to start with a -.
P.S. On my mac I have Homebrew installed, so I was able to install parallel and convert with
brew install parallel
brew install imagemagick
If your image files have different extensions:
for f in *; do convert -resize 800x600 -- "$f" "${f%.*}-resized.${f##*.}"; done

Resources