JS
 New Member Posts:4

 |
| 10 Mar 2010 07:52 AM |
|
I am super new to powershell and I am currently trying to capture image attributes using the below script:
[reflection.assembly]::loadfile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") "Name|SizeInBytes|Width|Height" >> C:\JPGInfo.txt $filepath="C:\Images\" $imageFiles = gci -recurse C:\Images\ -include *.jpg foreach ($image in $imageFiles) { (gci $image).Name+"|"+(gci $image).Length+"|"+(New-Object -TypeName system.drawing.bitmap $image).Width+"|"+(New-Object -TypeName system.drawing.bitmap $image).Height >> C:\JPGInfo.txt }
But I am getting errors similar to:
Cannot convert argument "0", with value: "C:\Images\Blah.jpg", for "Bitmap" to type "System.Drawing.Image": "Cannot convert the "C:\Images\Blah.jpg" value to type "System.IO.FileInfo" to type "System.Drawing.Image"."
CategoryInfo: InvalidOperation : (:) [New-Object], MethodException FullyQualifiedErrorID: ConstructorInvoikedThrowException, Microsoft.PowerShell.Commands.NewObjectCommand
Any help would be appreciated.
JS
|
|
|
|
|
George Howarth
 Basic Member Posts:360

 |
| 10 Mar 2010 08:14 AM |
|
Try this: function _Get-ImageStream { param ($File) $image = [System.Drawing.Image]::FromFile($File) $imageStream = New-Object System.IO.MemoryStream $image.Save($imageStream, [System.Drawing.Imaging.ImageFormat]::Jpeg) return $imageStream } [System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") "Name|SizeInBytes|Width|Height" >> C:\JPGInfo.txt $path = "C:\Images\" $imageFiles = Get-ChildItem -Recurse $path -Include *.jpg foreach ($image in $imageFiles) { $image.Name + "|" + $image.Length + "|" + (_Get-ImageStream -File $image).Width + "|" + (_Get-ImageStream -File $image).Height >> C:\JPGInfo.txt } |
|
|
|
|
JS
 New Member Posts:4

 |
| 10 Mar 2010 09:40 AM |
|
Wow, thank you for the timely reply. I tried this script and it only outputs the image name and the file size while leaving Width & Length blank. The errors are gone, is there something else I am missing?
|
|
|
|
|
George Howarth
 Basic Member Posts:360

 |
| 10 Mar 2010 10:03 AM |
|
Hmmm, I think that was my bad. I forgot the .FullName property for the image. Try this: function _Get-ImageStream { param ($File) $image = [System.Drawing.Image]::FromFile($File) $imageStream = New-Object System.IO.MemoryStream $image.Save($imageStream, [System.Drawing.Imaging.ImageFormat]::Jpeg) return $imageStream } [System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") "Name|SizeInBytes|Width|Height" >> C:\JPGInfo.txt $path = "C:\Images\" $imageFiles = Get-ChildItem -Recurse $path -Include *.jpg foreach ($image in $imageFiles) { $name = $image.Name $length = $image.Length $imageStream = _Get-ImageStream -File $image.FullName $width = $imagestream.Width $height = $imageStream.Height "$name|$length|$width|$height" >> C:\JPGInfo.txt } |
|
|
|
|
JS
 New Member Posts:4

 |
| 10 Mar 2010 11:27 AM |
|
The output is still the same. (Name|Size||) The script runs for 3-4 seconds on 16 jpgs so I know that the script is running against those images, I am just not sure why those attributes are not being output. |
|
|
|
|
George Howarth
 Basic Member Posts:360

 |
| 10 Mar 2010 11:53 AM |
|
Ugh, sorry. Change "return $imageStream" to "return $image". That's why it wasn't working. function _Get-ImageStream { param ($File) $image = [System.Drawing.Image]::FromFile($File) $imageStream = New-Object System.IO.MemoryStream $image.Save($imageStream, [System.Drawing.Imaging.ImageFormat]::Jpeg) return $image } [System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") "Name|SizeInBytes|Width|Height" >> C:\JPGInfo.txt $path = "C:\Images\" $imageFiles = Get-ChildItem -Recurse $path -Include *.jpg foreach ($image in $imageFiles) { $name = $image.Name $length = $image.Length $imageStream = _Get-ImageStream -File $image.FullName $width = $imagestream.Width $height = $imageStream.Height "$name|$length|$width|$height" >> C:\JPGInfo.txt } |
|
|
|
|
JS
 New Member Posts:4

 |
| 11 Mar 2010 07:58 AM |
|
This works perfectly. Unfortunately, I am trying to get these attributes for over 1.5M images and I am running into a memory issue around 20k images. Is there any way to dispose objects held in memory for this? |
|
|
|
|
George Howarth
 Basic Member Posts:360

 |
| 11 Mar 2010 08:20 AM |
|
Yes, there is. In hindsight, I've realized the script can be simplified to this also: [System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll") "Name|SizeInBytes|Width|Height" >> C:\JPGInfo.txt $path = "C:\Images\" $images = Get-ChildItem -Recurse $path -Include *.jpg foreach ($image in $images) { $name = $image.Name $length = $image.Length $imageFile = [System.Drawing.Image]::FromFile($image.FullName) $width = $imageFile.Width $height = $imageFile.Height "$name|$length|$width|$height" >> C:\JPGInfo.txt $imageFile.Dispose() } |
|
|
|
|
PoSherLife
 Basic Member Posts:364

 |
| 11 Mar 2010 12:49 PM |
|
Just a few things:
Why the output to a txt file? If a CSV will work this is a more efficient way to do it. It gives the ability to more effectively save the data as an object, then only write to disk 1x.
When you load an assembly using [void] will keep the console output cleaner.
Instead of creating several object, just create a single object with multiple properties. I'm sure this is a VERY fast script already, but its just a good practice to keep everything tidy and quick. ======================================== [Void][System.Reflection.Assembly]::LoadFile( "C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll")
$path = "C:\Images\"
$data = Get-ChildItem -Recurse $path -Include *.jpg | % { $imageFile = [System.Drawing.Image]::FromFile($_.FullName) ; New-Object PSObject -Property @{ name = $_.Name length = $_.Length width = $imageFile.Width height = $imageFile.Height } } $data | Export-Csv C:\JPGInfo.csv -NoTypeInformation |
|
| When at first you don't succeed Step-Into
http://theposherlife.blogspot.com
http://www.jandctravels.com |
|
|