LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   list graphics only for a IFS loop (https://www.linuxquestions.org/questions/programming-9/list-graphics-only-for-a-ifs-loop-778723/)

wonderfullyrich 12-29-2009 11:40 AM

list graphics only for a IFS loop
 
I've got a script processing a timelapse stills that I'm again trying to improve and ran into a question I can't figure out with google. How do I modify this IFS loop so I list only graphic files, say case insensitive extensions of jpg, gif, png, and maybe bmp? Most of the time I'm sure i'll be dealing with Jpegs only, but I'd rather not limit it?.


Code:

IFS='
' files=( $(/bin/ls -1 --ignore=resized_to_*) )

for (( i = 0; i < ${#files[*]}; i++ ))
do
  file="${files[$i]}"
  <commands>
done

Thanks,
Rich

acid_kewpie 12-29-2009 04:16 PM

What do you actually want to do? Seems really quite odd what you're already doing, why are you using a numerical for loop when you can just loop through the array elements anyway? Quite probably easiest to just pass the ls output direct to xargs or a while loop, really.

find . -iname *.jpg -o -iname *.bmp ... -print | while read FILENAME
do
<stuff>
done

osor 12-29-2009 05:26 PM

You could simply grep for each file extension you want:
Code:

IFS='
' for file in $(/bin/ls -1 --ignore=resized_to_*)
do
  if ! echo "$file" | grep -qiE '\.(jpg|png|gif|svg|bmp)$'
  then
    continue
  fi
  <commands>
done

Or, if you want to use magic instead of extensions, grep for image or bitmap from file output:
Code:

IFS='
' for file in $(/bin/ls -1 --ignore=resized_to_*)
do
  if ! file "$file" | grep -qiE 'image|bitmap'
  then
    continue
  fi
  <commands>
done

Of course you might inadvertently pick up disk images or bitmaps, but usually you wouldn’t keep these in the same directory.

wonderfullyrich 12-29-2009 05:34 PM

I'm using a numerical loop so I can display the progress via Zenity. Eventually I'd like to bring the whole process into a gui interface that is easier for others to use, but this is an incremental process and I keep running into errors on the processing when imagemagick tries to work on thumbnail.db, or a sub-directory, or etc.

Can I use
Code:

find . -iname *.jpg -o -iname *.bmp -o -iname *.png -o -iname *.gif -o -iname *.jpeg -print | while read FILENAME
in place of the
Code:

/bin/ls -1 --ignore=resized_to_*
and retain the zenity output?


Also the full script is below for context.

Thanks,
Rich


Code:


#!/bin/bash

imgsize="720x480"
himgsize=resized_to_$imgsize
watermarkpng="/path/to/directory/80x15.png"

#create directory if not exist and at least one image to process
#this line needs if exists option
echo --------- create directory "$himgsize"
if [ ! -d $himgsize  ] ;then
                mkdir $himgsize
fi



#iterate through selected images, resize, and rename
echo --------- processing images


IFS='
' files=( $(/bin/ls -1 --ignore=resized_to_*) )

(for (( i = 0; i < ${#files[*]}; i++ ))
do
  file="${files[$i]}"
        let "compteur += 1"
        totalfiles=${#files[*]}
        echo "# Processing image $compteur / ${#files[*]}  $file ..."
        convert +page -type TrueColor -filter sinc -geometry $imgsize -font Times-Roman -pointsize 14 -gravity southeast \
        -draw "image Multiply 122,0 0,0 '$watermarkpng'" \
        -fill white -annotate +1+1 'wonderfullyrich.com' \
        -fill black -annotate +0+0 'wonderfullyrich.com' \
        $file $himgsize/$file
        let "progress = compteur*100/${#files[*]}"
        echo $progress

done) |
        zenity --progress --auto-close --title="Scaling images"  --text="Processing images ..." --percentage=0

outputfilename=${PWD##*/}
echo --------- ${outputfilename} images processed
echo
echo --------- starting video encode


if [ -e ../${outputfilename}.mpg  ] ;

then
DATE=`date +%Y%m%e-%H%M`
outputfilename=${outputfilename}_$DATE

fi

mencoder mf://$himgsize/*.JPG -mf w=720:h=480:fps=24:type=JPG -of mpeg -mpegopts format=mpeg2:tsaf:muxrate=5270 -o ../${outputfilename}.mpg -oac lavc -lavcopts acodec=mp2:abitrate=224 -ovc lavc -lavcopts vcodec=mpeg2video:vbitrate=4096:keyint=15:mbd=2 2>&1 | awk -vRS="\r" '$1 ~ /Pos/ {gsub(/Pos:/," ");gsub(/%\)/," ");gsub(/ \(/," ");print $3"\n#Position :\\t"$1"\\nFrame :\\t"$2"\\nPercentage :\\t"$3"%\\nFrame Rate :\\t"$4"\\nTime Remaining :\\t"$6; fflush();}' | zenity --progress --auto-kill --auto-close

echo --------- ${outputfilename}.mpg has been created


wonderfullyrich 12-30-2009 03:50 AM

Thanks osor, the magic version is exactly what I'm looking for however, I seems to be missing something. When I put either version of the if-then-if grep test into the loop it doesn't return any values. (Below is the bash -x result for the intial part of the loop using the extension grep.)

Code:

$ bash -x ~/guiconvert720x480.sh
+ imgsize=720x480
+ himgsize=resized_to_720x480
+ himgsize1=resized_to_640x480
+ watermarkpng=~/80x15.png
+ echo --------- create directory resized_to_720x480
--------- create directory resized_to_720x480
+ '[' '!' -d resized_to_720x480 ']'
+ echo --------- processing images
--------- processing images
+ IFS='
'
+ files=($(/bin/ls -C1 --ignore=resized_to_*))
++ /bin/ls -C1 '--ignore=resized_to_*'
+ (( i = 0 ))
+ (( i < 399 ))
+ echo ''
+ zenity --progress --auto-close '--title=Scaling images' '--text=Processing images ...' --percentage=0
+ grep -qiE '\.(jpg|png|gif|svg|bmp)$'
+ continue
+ (( i++  ))
+ (( i < 399 ))
+ echo ''

As I understand it grep is -q is quiet, -i ignores case, and -E enables RegEx. I tried this
Code:

ls -1 | grep -qiE '\.(jpg|png|gif|svg|bmp)$'
on a directory full of my timelapse images but it returns nothing. Omiting -q option it returns the files, but not being well refined in scripting techniques I'm not sure what this is doing or how it's failing. Any ideas what I'm missing?

Thanks,
Rich

osor 12-30-2009 09:46 AM

Quote:

Originally Posted by wonderfullyrich (Post 3808657)
Thanks osor, the magic version is exactly what I'm looking for however, I seems to be missing something. When I put either version of the if-then-if grep test into the loop it doesn't return any values. (Below is the bash -x result for the intial part of the loop using the extension grep.)

As acid_kewpie has stated, your script is written in a strange manner. You have given us the old script, but not the changes you made. I assume you have replaced this construct:
Code:

IFS='
' files=( $(/bin/ls -1 --ignore=resized_to_*) )

(for (( i = 0; i < ${#files[*]}; i++ ))
do
  file="${files[$i]}"
        let "compteur += 1"

with this
Code:

( IFS='
' for file in $(/bin/ls -1 --ignore=resized_to_*)
do
  if ! echo "$file" | grep -qiE '\.(jpg|png|gif|svg|bmp)$'
  then
    continue
  fi
        let "compteur += 1"

You may (as you have probably guessed) have instead done this (but not with magic):
Code:

( IFS='
' for file in $(/bin/ls -1 --ignore=resized_to_* | grep -iE '\.(jpg|png|gif|svg|bmp)$')
do
        let "compteur += 1"

or even this:
Code:

( ls -1 --ignore=resized_to_* | grep -iE '\.(jpg|png|gif|svg|bmp)$' | while read file
do
        let "compteur += 1"

Quote:

Originally Posted by wonderfullyrich (Post 3808657)
As I understand it grep is -q is quiet, -i ignores case, and -E enables RegEx. I tried this
Code:

ls -1 | grep -qiE '\.(jpg|png|gif|svg|bmp)$'
on a directory full of my timelapse images but it returns nothing. Omiting -q option it returns the files, but not being well refined in scripting techniques I'm not sure what this is doing or how it's failing. Any ideas what I'm missing?

Yes there is. The point of the “grep -q” is not to print the files (although that would be one way to do it—see above) but to return a truth value which will be tested. For example:
Code:

$ echo "foo.jpg" | grep -qiE '\.(jpg|png|gif|svg|bmp)$'
$ echo $?
0
$ echo "bar" | grep -qiE '\.(jpg|png|gif|svg|bmp)$'
$ echo $?
1



All times are GMT -5. The time now is 12:28 AM.