メモ
- GetDetailsOfではなくImage.PropertyItemsによる取得を考える
using namespace System.Collections.Generic
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
Add-Type -AssemblyName @(
"Microsoft.VisualBasic"
"System.Drawing"
)
Add-Type -Language CSharp -ReferencedAssemblies Microsoft.CSharp -TypeDefinition @'
namespace MyNS {
using System.Runtime.InteropServices;
public static class Array {
public static dynamic[] Sort(dynamic[] obj) {
dynamic[] ret = (dynamic[])obj.Clone();
System.Array.Sort(ret, (x, y) => StrCmpLogicalW(x.Name, y.Name));
return ret;
}
[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(
[MarshalAs(UnmanagedType.LPWStr)] string psz1,
[MarshalAs(UnmanagedType.LPWStr)] string psz2
);
}
}
'@
try {
$str = [Microsoft.VisualBasic.Interaction]::InputBox("パス", $Host.Name, "$HOME\Desktop", -1, -1)
Set-Location -LiteralPath (Split-Path -LiteralPath $str)
$psObjs = @( & {
$ext = [string]( @(
'^\.bmp$', '^\.dib$', '^\.jpg$', '^\.jpeg$', '^\.jpe$', '^\.jfif$', '^\.gif$', '^\.tif$', '^\.tiff$', '^\.png$'
) -join '|' )
$fs = @(Get-ChildItem -Recurse -Depth 2 -File).Where({$_.Extension -match $ext})
$grByDirName = [MyNS.Array]::Sort(@($fs | Group-Object -Property DirectoryName))
$fList = [List[IO.FileInfo]]::new()
for ($i = 0; $i -lt $grByDirName.Length; $i++) {
$fList.AddRange([MyNS.Array]::Sort([IO.FileInfo[]]$grByDirName[$i].Group))
}
return $fList
} )
$propNameImgPropItemSet = [HashSet[string]]::new()
foreach ($psObj in $psObjs) {
if ($psObj.Extension -notmatch '^\.bmp$|^\.gif$|^\.jpg$|^\.png$|^\.tif$') {
continue
}
try {
$fStream = $null
$img = $null
$fStream = [IO.File]::Open(
$psObj.FullName, [IO.FileMode]::Open, [IO.FileAccess]::Read,
[IO.FileShare]::Delete -bor [IO.FileShare]::ReadWrite
)
$img = [Drawing.Image]::FromStream($fStream, $false, $false)
$propPSObj = [ordered]@{
ImgColorDepth = [Drawing.Image]::GetPixelFormatSize($img.PixelFormat)
ImgDpiX = $img.HorizontalResolution
ImgDpiY = $img.VerticalResolution
ImgWidth = $img.Width
ImgHeight = $img.Height
}
foreach ($propItem in $img.PropertyItems) {
$propName = "0x$($propItem.Id.ToString('X4'))"
[void]$propNameImgPropItemSet.Add($propName)
$value = "Type $($propItem.Type) / Len $($propItem.Len)"
switch ($propItem.Type) {
1 {
$value += "`n"
}
2 {
$encoding = [Text.ASCIIEncoding]::new()
$str = $encoding.GetString($propItem.Value, 0, $propItem.Len - 1)
if ($propItem.Id -eq 0x0132) {
$dateString = $str
$format = "yyyy:MM:dd HH:mm:ss"
$provider = [Globalization.CultureInfo]::InvariantCulture
$strDate = [DateTime]::ParseExact($dateString, $format, $provider).ToString()
$value += "`n=> $strDate"
}
else {
$value += "`n=> $str"
}
}
3 {
$value += "`n=> $([BitConverter]::ToUInt16($propItem.Value, 0))"
}
4 {
$value += "`n=> $([BitConverter]::ToUInt32($propItem.Value, 0))"
}
5 {
$num = [BitConverter]::ToUInt32($propItem.Value, 0)
$den = [BitConverter]::ToUInt32($propItem.Value, 4)
$value += "`n=> $num / $den"
}
10 {
$num = [BitConverter]::ToInt32($propItem.Value, 0)
$den = [BitConverter]::ToInt32($propItem.Value, 4)
$value += "`n=> $num / $den"
}
default {
$value += "`n=> $([BitConverter]::ToString($propItem.Value))"
}
}
$propPSObj.Add($propName, $value)
}
$img.Dispose()
$fStream.Dispose()
$psObj | Add-Member -NotePropertyMembers $propPSObj
}
catch {
if ($null -ne $img ) { $img.Dispose() }
if ($null -ne $fStream) { $fStream.Dispose() }
throw
}
}
$props = [List[string]]::new()
$props.AddRange([string[]]@("BaseName", "Extension", "DirectoryName"))
$props.AddRange([string[]]@("ImgColorDepth", "ImgDpiX", "ImgDpiY", "ImgWidth", "ImgHeight"))
$props.AddRange([string[]]@($propNameImgPropItemSet | Sort-Object))
$outObjs = @($psObjs | Select-Object -Property $props)
$html = $outObjs | ConvertTo-Html -Head ( @(
'<style>'
' table { border-collapse: collapse; }'
' th, td { white-space: pre; word-break: keep-all; border: thin solid black; }'
'</style>'
) -join "`n" )
$html | Out-File -FilePath "${env:USERPROFILE}\Desktop\OutputTest.html"
$outObjs | Out-GridView
}
catch {
throw
}