Page 1 of 2

Index problem with identify in DOS FOR loop

Posted: 2010-03-15T10:11:31-07:00
by paddy
Hi,

I've been using IM for a few trivial things in the past, but I'm now trying to automate a lot of what I do within a set of DOS batch files.

So far, I haven't come across any problems that I haven't been able to solve, but now I've encountered a problem which appears to be so simple, yet it has me stumped, and I just can't find the solution.

Basically I've got a simple FOR loop, and for each file encountered in the input folder I want to do some dynamic stuff related to the dimensions of the file. For example: I want to retrieve the pixel dimensions of each file as it's processed, and then use this information to make some decisions, so I need to assign these values to a couple of DOS shell variables.
(I'm currently testing this with just 2 files of different size. ) The first file (alphabetically) is 640x425 pixels, and the second is 400x266.

Here's the code:

Code: Select all

for /f %%a in ('dir /b %infolder%\*.jpg') do 
( 
	ECHO Processing file: "%%a" 
	SET width='identify -format "%%[fx:w]" %%a'
	SET height='identify -format "%%[fx:h]" %%a'
	
	echo %width% %height%

	REM call another batch file here to do more work....
               ((I want to pass in the width and height as parameters)

        REM call dowork.bat .... (commented out for clarity)

       ....
)
and here's the debugging output:

Code: Select all

Processing file: "_DSC7795.JPG"
400 266

Processing file: "_DSC7796Copy.JPG"
400 266
Note that the reported dimensions for each iteration of the loop matches the size of the last file only, whereas accessing the file attributes using identify as follows in the subordinate dowork.bat (called once for each file when re-activated) returns the correct values...(as you can see in the output below).

Code: Select all

echo "dowork:"
set fred=%infolder%\%imgname%%imgsuffix%
FOR /F %%i IN ('identify -format "%%[fx:w]" %fred%') DO SET width=%%i
echo. %width%
FOR /F %%i IN ('identify -format "%%[fx:h]" %fred%') DO SET height=%%i
echo. %height%
I would have expected to see the following output if this loop was working correctly:

Code: Select all

Processing file: "_DSC7795.JPG"
640 425
dowork:
 640
 425
Processing file: "_DSC7796Copy.JPG"
400 266
dowork:
 400
 266
I suspect that there's some strange interaction with the identify command ... ie. perhaps identify parses the whole folder on each iteration of the FOR loop and returns the last result only (rather than returning the attributes of the individual file on each iteration, which is what I want).

Sorry,... I'm embarrassed to be asking this question because this seems like such a simple issue, but it's got me completely stumped!!!

Maybe there's a better method than using identify to get this information???

Comments welcome... but please, no "use LINUX", use CYGWIN" comments (I have too much invested in these DOS batch files already 8) )

Thanks in advance...

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T12:51:31-07:00
by el_supremo
Which version of Windows are you using? The SET statements in your first block of code don't work on my Win XP Pro system.

Pete

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T15:42:27-07:00
by fmw42
you could try

SET width='identify -format "%%w" %%a'

similar for height

perhaps your version of IM is older than fx. what version are you using?

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T16:52:35-07:00
by paddy
Sorry, forgot to post that info.

OS: XP Home SP3 (Version 5.1.2600)
and..
Version: ImageMagick 6.5.9-4 2010-02-09 Q16 http://www.imagemagick.org
fmw42 wrote:you could try

SET width='identify -format "%%w" %%a'

similar for height
Thanks. Tried that already -- Gives exactly the same result.
(Like I said, I've tried everything to no avail! :( )

This seems very weird to me!!!
el_supremo wrote:Which version of Windows are you using? The SET statements in your first block of code don't work on my Win XP Pro system.
Hmmm..... perhaps your version of IM pre-dates FX (as fmw42 mentions above)?

Have you also tried using the "%%w" format instead of FX?


Did either of you guys run my code? I'd be interested to compare your output with mine.

(Just drop a couple of JPGs into a folder and set infolder to that location)

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T17:17:44-07:00
by fmw42
Sorry, I am using a Mac. Don't know much about Windows/DOS

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T17:23:40-07:00
by el_supremo
I created a directory with only one jpg file in it - test.jpg. I then used this batch script in that directory:

Code: Select all

for /f %%a in ('dir /b *.jpg') do (
ECHO Processing file: "%%a" 
SET width='identify -format "%%[fx:w]" %%a'
echo %width%
)
and the output is:

Code: Select all

Processing file: "test.jpg"
'identify -format "%[fx:w]" test.jpg'
It is not executing the identify but is interpreting everything to the right of the equal sign as a literal string except that it does do the substitution of the filename.
My system is also Win XP SP3 and I was not aware that you could get DOS to execute a command and store its output as the target of a SET variable statement. I can't find any documentation that says that it will work.
Hmmm..... perhaps your version of IM pre-dates FX
My IM is 6.5.9-10 Q8 so -fx isn't the problem.


Pete

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T17:33:33-07:00
by fmw42
see http://www.imagemagick.org/Usage/windows/#calc_set

perhaps that will give you some clues how to do it

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T17:50:33-07:00
by paddy
el_supremo wrote:I created a directory with only one jpg file in it - test.jpg. I then used this batch script in that directory:
....
and the output is:

Code: Select all

Processing file: "test.jpg"
'identify -format "%[fx:w]" test.jpg'
It is not executing the identify but is interpreting everything to the right of the equal sign as a literal string except that it does do the substitution of the filename.
Thanks. My testing (in interactive CMD mode, rather than batch mode) confirms the same:
C:\TEMP>identify -format %"[FX:w]" dsc7795.jpg
640

C:\TEMP>set width='identify -format %"[FX:w]" dsc7795.jpg'

C:\TEMP>echo %width%
'identify -format %"[FX:w]" dsc7795.jpg'

C:\TEMP>
My system is also Win XP SP3 and I was not aware that you could get DOS to execute a command and store its output as the target of a SET variable statement. I can't find any documentation that says that it will work.
See here: http://www.imagemagick.org/Usage/windows/#calculations
My IM is 6.5.9-10 Q8 so -fx isn't the problem.
Pete
I agree that FX is not the problem.

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T17:59:54-07:00
by paddy
fmw42 wrote:see http://www.imagemagick.org/Usage/windows/#calc_set

perhaps that will give you some clues how to do it
Thanks frmw42. That's the same page that I referred to in my reply to Pete above. :D

The only significant difference in syntax that I can see is that the documentation on that page substitutes a batch file parameter (%1), rather than a plain environment variable::

eg. FOR /F %%i IN ('identify -format "%%[fx:w]" %1') DO SET width=%%i

whereas, I probably need to do something like this within my outer loop:

FOR /F %%i IN ('identify -format "%%[fx:w]" %%a') DO SET width=%%i
FOR /F %%i IN ('identify -format "%%[fx:h]" %%a') DO SET height=%%i

However, I've tried this already, and it also doesn't work!!

I'm sure it's a problem with the DOS evaluation of the string substitution. (As Pete and I have separately confirmed above, identify works perfectly at the command line, but not when substituted into a string in DOS).
At this stage, I'm no closer to solving it!

Thanks for the help though!

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T19:59:49-07:00
by el_supremo
The problem is that when DOS executes the FOR statement it only does variable substitution once when the FOR statement is read.
See this page: http://www.computerhope.com/sethlp.htm
starting with "Finally, support for delayed environment variable expansion has been added."

Pete

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-15T21:09:19-07:00
by paddy
el_supremo wrote:The problem is that when DOS executes the FOR statement it only does variable substitution once when the FOR statement is read.
See this page: http://www.computerhope.com/sethlp.htm
starting with "Finally, support for delayed environment variable expansion has been added."

Pete
Thanks very much Pete. That describes the exact issue.
As with most things to do with DOS batch scripts, the simplest tasks are much harder than they need to be! :?

Anyway. from reading that page and with a bit of trial and error I think I have a solution that works:

Code: Select all

set /A i="0"
set fred=""
for /f %%a in ('dir /b %infolder%\*.jpg') do ( 
	set /A i="!i! + 1"
	ECHO Processing file !i! "%%a" 
	
	set fred=%%a
	ECHO FRED:!fred!
	for /f %%i in ('identify -format %%"[fx:w]" %infolder%\!fred!') do SET width=%%i
	for /f %%j in ('identify -format %%"[fx:h]" %infolder%\!fred!') do SET height=%%j
	
	echo Correct: !width! !height!
	echo Dodgy: %width% %height%

       ......

)
The only downside is that I must remember to always start the CMD window with the /V switch....Such is life!!... 8)

Thanks for the help guys.... I hope that's the last show-stopper I encounter.

P

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-17T09:37:17-07:00
by fmw42
I pointed this topic to Wolgang Hugemann, who wrote the Usage Under Windows page. He asked me to post the following as he is out of town.

Take a look at his Usage Under Windows page regarding "enabling delayed expansion"

As I am not a Windows user, I don't understand much of this, but I thought I would pass it on. Perhaps that is what you are doing with the /V switch?

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-17T10:46:55-07:00
by kankwayot
also, you can advantageously replace

Code: Select all

for /f %%i in ('identify -format %%"[fx:w]" %infolder%\!fred!') do SET width=%%i
for /f %%j in ('identify -format %%"[fx:h]" %infolder%\!fred!') do SET height=%%j
by

Code: Select all

for /f %%i in ('identify -format "width=%%[fx:w]\nheight=%%[fx:h]" %infolder%\!fred!') do SET %%i

:: verification
for %%d in (width height) do ( echo %%d is !%%d! )
and presto, you've divided by 2 the overhead of calling identify !

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-21T10:43:20-07:00
by paddy
fmw42 wrote:I pointed this topic to Wolgang Hugemann, who wrote the Usage Under Windows page. He asked me to post the following as he is out of town.

Take a look at his Usage Under Windows page regarding "enabling delayed expansion"

As I am not a Windows user, I don't understand much of this, but I thought I would pass it on. Perhaps that is what you are doing with the /V switch?
Do you mean the page that you earlier referred me to (above)?
I have read that page, but did you (or Wolgang Hugemann) have further comments or clarifications to make in addition to your earlier post?

Thanks
kankwayot wrote:also, you can advantageously replace
....
[/code]and presto, you've divided by 2 the overhead of calling identify !
Thanks! ... That is a useful (if syntactically challenging :D) optimization.
I've just now incorporated that into my code and it works well.

EDIT: ** IPTC issue moved to a new thread. ** here: viewtopic.php?f=1&t=15825

Re: Index problem with identify in DOS FOR loop

Posted: 2010-03-21T11:30:16-07:00
by fmw42
Do you mean the page that you earlier referred me to (above)?
I have read that page, but did you (or Wolgang Hugemann) have further comments or clarifications to make in addition to your earlier post?
Yes, but all I know was that he said to look at the part about "enabling delayed expansion"

Sorry I cannot be of more help. Perhaps when he gets back, he can comment further.