1

The below is supposed to go through a folder containing jpgs and replace the filenames with nnnZ.jpg, skipping a number if the image is in landscape.

I've seen the examples at https://learn.microsoft.com/en-us/powershell/scripting/learn/deep-dives/everything-about-if?view=powershell-7.1 and it doesn't look like there's a problem with syntax of the if statement or the condition ($w -gt $h), but the 'then' is being executed every time, even though all but one of the images in the folder are in portrait. The values of $w and $h are correct (per the echo) so I don't understand what is going wrong.

Edit: or are those values actually strings, and is that what the %s mean?

Get-ChildItem | foreach {
  $w=$(magick identify -format '%w' $_)
  $h=$(magick identify -format '%h' $_)
  $flag="false"
  if ($w -gt $h) {
    $c++
    $flag="true"
  }
  $newname = "$($c)Z.jpg".Padleft(8,'0')
  Rename-Item $_ -NewName $newname
  $c++
  echo $w $h $flag $c
}
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206
rchivers
  • 155
  • 4

1 Answers1

1

In order not to have yet another 'unanswered' question on SO, here my comment as answer:

the code for $w=$(magick identify -format '%w' $_) and $h=$(magick identify -format '%h' $_) produces strings, not integer values.

Cast these to int using

[int]$w = $(magick identify -format '%w' $_)
[int]$h = $(magick identify -format '%h' $_)

so the comparison would do what you expect.


As mklement0 commented, in the above lines, the SubExpression operator $() is not needed, although it doesn't harm in getting the results.
Basically, while a simple ( ) grouping expression means 'execute this part first', a subexpression $( ) means 'execute this first and then treat the result like a variable'. It can contain multiple semicolon ; separated statements.

If the files you need to get the width and height for are all of type BMP, GIF, JPEG, PNG or TIFF, you don't need to use an external application like ImageMagick to get the size, because the .NET System.Drawing.Image class can handle those very well:

# open the image file
$img = [System.Drawing.Image]::FromFile($_.FullName)
$w = $img.Width   # these are Int32 values
$h = $img.Height
# dispose of this image object
$img.Dispose()
Theo
  • 57,719
  • 8
  • 24
  • 41
  • @mklement0 What do the $s do? I got that line from somewhere or other and just copied the whole thing. – rchivers Nov 21 '20 at 09:33
  • @rchivers, see Theo's update, but let me add that `$(...)` is only ever needed in two cases: if you need to embed entire _statement(s)_, notably conditionals and loops, into a statement, or to embed any expression or statement(s) inside `"..."`, an expandable (interpolating) string. A single statement on the RHS of an assignment doesn't even need `(...)`, the grouping operator, which itself is sufficient for nesting a single command or expression. While not likely, the unnecessary use of `$(...)` can have side effects - see [this answer](https://stackoverflow.com/a/58248195/45375). – mklement0 Nov 21 '20 at 13:37