LinuxQuestions.org
Welcome to the most active Linux Forum on the web.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 04-15-2012, 12:02 PM   #1
xeyve
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Rep: Reputation: Disabled
Question bash script to resize each image in a directory


Hi everyone, I'm a bit noobish with scripting and I want to automate the hard and long work that is the mannually resize hundreds of image with GIMP. For those that are interested I do that because I want to resize a texture pack for minecraft.

There is many thing I don't really know how to do and for those I need a bit of help, so here are some of theme:
  • I need to pass sucesively on each image in the directory himself and in directory that are inside the main one. Some time the image are even in a third or fourth directory
  • I need to know the size of the image so I can resize it with the correcte ratio. I have thincked about using imagemagick's identify command, but then I don't know how to get the size out of the output. Maybe using awk or somthing.
  • Sometime the image sizes are not perfect ( 513x512 insted of 512x512), so it would be great to be able to round the size up
  • I aslo need to copy the output (after the image is resized) in another directory but I also need to keep the same hierarchy.

I dont't know if I'm clear so here a exemple: input_pack/item/mod/TC2/dirt_block.png need to be resized and copied in outpout_pack/item/mod/TC2/dirt_block.png

Thanks in advence for your help and if I have new probleme I'll probably come back and ask my question here
 
Old 04-15-2012, 12:22 PM   #2
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,842

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
this is not the bash. You need a graphical tool to do this. Bash can only be used to collect filenames and start the process.
For example ufraw can resize the picture to a given size (ratio depends on the longer side) and also you can define an output folder. I recommend you to search/google for "batch resize images" or similar, do not try to implement it in awk.
 
Old 04-15-2012, 12:39 PM   #3
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
Quote:
Originally Posted by pan64 View Post
this is not the bash. You need a graphical tool to do this. Bash can only be used to collect filenames and start the process.
For example ufraw can resize the picture to a given size (ratio depends on the longer side) and also you can define an output folder. I recommend you to search/google for "batch resize images" or similar, do not try to implement it in awk.
Sorry, but you are wrong, you can do this completely in bash.

I'm not gonna write it all for you tho, because it is tedious and you didn't provide enough info on what exactly needs to be done. However, here are some possibly useful commands or algorithms.

You can get the size of a png like:

Code:
identify 800px-Bridge-fan-cable-stayed.svg.png | awk '{ print $3}'
See:
http://imagemagick.org/script/comman...hnbn5#geometry
for geometry options on resizing.

For finding the files and executing commands on them:
http://www.grymoire.com/Unix/Find.html#uh-13

If you need it, there is a GIMP plugin for batch processing:
http://members.ozemail.com.au/~hodsond/dbp.html
 
Old 04-15-2012, 12:44 PM   #4
xeyve
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
I don't need any graphical tool other then imagemagick and I just need to pars the image size out of the output of the identify command. Also, I don't want to use batch I want to write a bash script
I don't want to implement anythingin awk, I just want to use it to pars an output.

What do you mean by this is not the bash ?

EDIT:
Thanks TeXMeX this is exactly what I needed. Could you explain the "awk '{ print $3}'" ?

Last edited by xeyve; 04-15-2012 at 12:49 PM.
 
Old 04-15-2012, 01:45 PM   #5
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
You can also use cut:

Code:
identify image.png | cut -d' ' -f 3
It prints field 3 separated by white space. I prefer awk because it takes any white space, while cut only takes one type.

If you post more specific things, I may write the script for you if I have time.
 
Old 04-15-2012, 01:46 PM   #6
xeyve
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
I have a new probleme

Here what I have done so far :
Code:
#! /bin/sh

INPUT_DIR=/home/xeyve/DATA/Document/Minecraft/texture\ pack/Sphax
OUTPOUT_DIR=/home/xeyve/DATA/Document/Minecraft/texture\pack/Sphax\ 32
INPUT_SIZE=128
OUTPOUT_SIZE= 32 


RATIO= $($INPUT_SIZE/$OUTPOUT_SIZE)

cd "$INPUT_DIR"

for file in $(find |grep .png)
do
SIZE=$(identify $file |awk '{ print $3}')
# problem here, I can't divide  the string "2048x2048"(exemple) by 4. I need to convert it to  a number, divide it then convert it back to a string. 
RESIZE= $($SIZE/$RATON)
convert $file --resize $RESIZE
done
the awk's output is a string in the format of "128x128" or "1024x1024". I need to devide those number by the ration ( 4 this time ) and then pass the new string to the convert command. The new string should look like "32x32" or "256x256" for the to exemple I have given.
 
Old 04-15-2012, 01:59 PM   #7
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,842

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
Quote:
Originally Posted by xeyve View Post
What do you mean by this is not the bash ?
I just wanted to say: this is not the optimal solution, bash is not planned to do such things, and again, bash itself is unable to do that (or really hard to implement it).
So you need to use some additional tools, like awk, perl, cut, identify or whatever you know or you find useful. From my point of view (and you do not need to agree) it can be solved easily by an image manipulation tool which has batch processing capabilities. I have a lot of pictures (those are made with a nikon) and I wanted to resize them (and I also modified other things, like brightness). ImageMagick's convert is a good command line tool for this, but maybe not suitable for you.
 
Old 04-15-2012, 02:25 PM   #8
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Quote:
Originally Posted by xeyve View Post
the awk's output is a string in the format of "128x128" or "1024x1024". I need to devide those number by the ration ( 4 this time ) and then pass the new string to the convert command. The new string should look like "32x32" or "256x256" for the to exemple I have given.
Code:
RESIZE=$(echo $SIZE | awk -Fx '{print $1/4 FS $2/4}')
Some manuals worth to read:
http://www.grymoire.com/Unix/Awk.html
http://www.gnu.org/software/gawk/manual/ (this is the official GNU awk guide)
 
Old 04-15-2012, 02:26 PM   #9
xeyve
LQ Newbie
 
Registered: Apr 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
well maybe It's not optimal but I also do it for the fun of learning, so it doesn't rellay matter.
I have solved the string to number conversion but now I am unable to convert it back to a string.

Quote:
#! /bin/sh

INPUT_DIR=/home/xeyve/DATA/Document/Minecraft/texture_pack/Sphax
OUTPOUT_DIR=/home/xeyve/DATA/Document/Minecraft/texture_pack/Sphax\ 32
INPUT_SIZE=128
OUTPOUT_SIZE=32


let "RATIO = $INPUT_SIZE / $OUTPOUT_SIZE"
#echo $RATIO


for file in $(find "$INPUT_DIR"|grep .png)
do

SIZE=$(identify $file |awk '{print $3}' |cut -d 'x' -f 2 )
let "RESIZE = $SIZE / $RATIO"
#STRING="$RESIZEx$RESIZE"
#this line doesn't work and I don't know any other way to do it
echo $STRING

done
 
Old 04-15-2012, 02:33 PM   #10
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Code:
#STRING="$RESIZEx$RESIZE"
#this line doesn't work and I don't know any other way to do it
This is because the x is a valid character in a variable name, so that bash tries to reference the value of a variable named "RESIZEx". Use braces to embed the variable name (this is the correct bash syntax):
Code:
STRING="${RESIZE}x${RESIZE}
Moreover you don't need to use cut to manage the output from awk:
Code:
STRING=$(identify $file | awk -v ratio=$RATIO '{split($3,a,"x"); print a[1]/ratio "x" a[2]/ratio}')
Check the links in my previous post to learn details about this powerful tool.
 
Old 04-15-2012, 02:40 PM   #11
Nominal Animal
Senior Member
 
Registered: Dec 2010
Location: Finland
Distribution: Xubuntu, CentOS, LFS
Posts: 1,723
Blog Entries: 3

Rep: Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948Reputation: 948
@colucix: Wouldn't it be better to make sure the result is an integer? Maybe printf("%.0fx%.0f\n", a[1]/ratio, a[2]/ratio) ? The %.0f pattern will print a correctly rounded integer.
 
1 members found this post helpful.
Old 04-15-2012, 02:42 PM   #12
colucix
LQ Guru
 
Registered: Sep 2003
Location: Bologna
Distribution: CentOS 6.5 OpenSuSE 12.3
Posts: 10,509

Rep: Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983Reputation: 1983
Of course! Thank you Nominal Animal!
 
Old 04-15-2012, 03:26 PM   #13
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
You can use variable expansion to extract the x and y values.
size="2048x1024"
xsize=${size%x*}; ysize=${size#*x}

Replace the 'x' with [xX:] to cover the 3 forms you might see, 1024x512, 1024X512, 1024:512. You could define functions to hide the details of extracting the dimensions, making the rest of the script easier to read and write.
 
Old 04-16-2012, 12:56 AM   #14
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
I don't have time now to really read this thread, but you might want to look through this list of preexisting imagemagick scripts. There may be one that does exactly what you want.

http://www.fmwconcepts.com/imagemagick/index.php


PS: Please use [code][/code] tags around your code and data, to preserve formatting and to improve readability. Please do not use quote tags, colors, or other fancy formatting.

Last edited by David the H.; 04-16-2012 at 12:57 AM.
 
Old 04-16-2012, 02:33 AM   #15
H_TeXMeX_H
LQ Guru
 
Registered: Oct 2005
Location: $RANDOM
Distribution: slackware64
Posts: 12,928
Blog Entries: 2

Rep: Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301Reputation: 1301
Just so you know there is a 32x32 texture pack:
http://bdcraft.net/download-purebdcr...-for-minecraft

Also, it's a bit more complicated because many textures are not square and are not 128. For example: 128x2048, 512x256, 512x512.

You should take this into account.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
bash script: use the directory of the script file as variable? phling Linux - Newbie 12 01-16-2010 07:16 PM
To rename files in a directory should I use Bash script or a Perl Script ? jamtech Programming 7 01-22-2008 11:25 PM
Bash Script - Resize Cover.png Images XaViaR Linux - General 3 09-04-2006 12:29 PM
Bash script to strip a certain directory out of directories in a directory? rylan76 Linux - General 3 08-29-2006 11:35 AM
bash script to resize gnome terminal ? smoker Linux - General 1 03-17-2006 03:32 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:47 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration