.jpg画像の保存に回転情報が含まれていることを知った
縦長画像をVBAでエクセルに挿入したら、縦横長がおかしくなり横に伸びてしまった。

VBAでは元画像の幅と高さを取得して、縦横比を維持して縮小してするような処理をしている。
最初はなぜ横に伸びているのかわからず。
VBEでトレースすると、思っていたのとは違い幅600 x 高さ400という感じで横長の状態のデータが保存されていることがわかった。ここでハテナ?
結論としては、縦長に見える画像でも実際には横長に保存されていて、回転情報が付加されていることがあるということ。
これは知らなかった。
確かに、これまでもなにかの機会にアプリやWebサイトへの画像貼り付けで画像の向きがおかしくなったとこがあったような。関係ありそう。

Exif(イグジフ)に、露出やF値などの撮影設定以外に、回転情報 Orientation という情報が入っているらしい。
カメラなど撮影機材の仕様で、撮影時の角度と向きをジャイロセンサーがキャッチしているのかな?
ビューアはOrientationの値を見て、回転を元に戻してから表示しているとのこと。
一方VBAではそんなことは知らず、回転情報は見ずに縦横幅しか見ていなかったためこんな問題に出会ったわけだ。
Macでjpgの情報を参照した例)

6が反時計回りに90°回転、8が反時計回りに270°回転、3が180°回転、1はそのままという具合だ。
レアケースとして、5や7の反転もある。
OrientationはWindowsのプロパティでは見ることができなかった。
つまり、VBA側で考慮不足(というか知らなかった)ことが原因。
Orientation(方向)の90°と270°だけを考慮して縦長と横長を取得するサンプル)
Sub ボタン1_Click()
Dim productImageFileName As String
Dim pic As Object
Dim w As Long, h As Long, ori As Integer
productImageFileName = "c:\abc.jpg"
' 画像の幅、高さを取得する
Set pic = LoadPicture(productImageFileName)
w = CLng(pic.width * 0.0378)
h = CLng(pic.height * 0.0378)
Debug.Print "▼オリジナル"
Debug.Print "幅=" & w
Debug.Print "高さ=" & h
Dim result As Variant
result = GetImageSizeWithOrientation(productImageFileName)
w = result(0)
h = result(1)
ori = result(2)
Debug.Print "▼回転考慮"
Debug.Print "幅=" & w
Debug.Print "高さ=" & h
Debug.Print "Orientation=" & ori
End Sub
Function GetImageSizeWithOrientation(filePath As String) As Variant
Dim img As Object
Set img = CreateObject("WIA.ImageFile")
img.LoadFile filePath
Dim width As Long
Dim height As Long
width = img.width
height = img.height
Dim orientation As Integer
orientation = 1 ' デフォルト(回転なし)
Dim prop As Object
For Each prop In img.Properties
If prop.PropertyID = 274 Then ' Orientation
orientation = prop.Value
Exit For
End If
Next
' Orientationに応じて補正
Select Case orientation
Case 6, 8 ' 90度 or 270度回転
Dim tmp As Long
tmp = width
width = height
height = tmp
End Select
GetImageSizeWithOrientation = Array(width, height, orientation)
End Function
実行結果の例)
▼オリジナル
幅=600
高さ=400
▼回転考慮
幅=400
高さ=600
Orientation=6
もう一つ、特定フォルダ内にたくさんあるjpgファイルの中から Orientation が設定された画像をリストするスクリプトを検討する。(ChatGPTに聞きながら)
PowerShellスクリプト)ファイル名:CheckOrientationJpg.ps1
$folder = "C:\images"
Add-Type -AssemblyName System.Drawing
Get-ChildItem $folder -Recurse | Where-Object {
$_.Extension -match '\.jpe?g$'
} | ForEach-Object {
try {
$img = [System.Drawing.Image]::FromFile($_.FullName)
if ($img.PropertyIdList -contains 274) {
$orientation = $img.GetPropertyItem(274).Value[0]
if ($orientation -in 6,8) {
[PSCustomObject]@{
FilePath = $_.FullName
Orientation = $orientation
Width = $img.Width
Height = $img.Height
}
}
}
$img.Dispose()
} catch {
$msg = "読み込み失敗:" + $_.Exception.Message
Write-Warning $msg
}
} | Format-List
PropertyID 274がOrientationとのこと。
そして、PowerShellを実行するバッチ)ファイル名:CheckOrientationJpg.bat
@echo off
powershell -ExecutionPolicy Bypass -File "%~dp0CheckOrientationJpg.ps1"
pause
実行結果は下記のような感じ。
FilePath : C:\images\1.jpg
Orientation : 6
Width : 120
Height : 80
FilePath : C:\images\2.jpg
Orientation : 8
Width : 120
Height : 80
