[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『指定フォルダー内のファイル(JPEG)のサイズを正方形に変換して同名で保存』(Muse)
ExcelのVBAで指定フォルダー内のファイル(JPEG)のサイズ(横1x縦1)を正方形に変換して同名で保存したい。
正方形のサイズとは、(横1+縦1)/2と縦と横が同じサイズのことです。
(変更時にアスペクト比を維持する必要はありません。)
以下を試して見ましたが変化がありません。
(コードは、ネットを参考にしました。)
Option Explicit
Sub RESIZETEST()
Dim folderPath As String
Dim fileName As String
Dim filePath As String
Dim newWidth As Long
Dim newHeight As Long
' 変換するフォルダーのパスを指定
folderPath = "C:\Users\mido\"
' フォルダー内のJPEGファイルを処理
fileName = Dir(folderPath & "*.jpg")
While fileName <> ""
filePath = folderPath & fileName
' 画像のサイズを取得
Dim oImageFile As Object
Set oImageFile = CreateObject("WIA.ImageFile")
oImageFile.LoadFile filePath
' 正方形のサイズを計算
newWidth = (oImageFile.Width + oImageFile.Height) \ 2
newHeight = newWidth
' 画像を正方形にリサイズして保存
Call WIA_ResizeImage(filePath, filePath, newWidth, newHeight, True, True)
fileName = Dir()
Wend
End Sub
Public Function WIA_ResizeImage(ByVal sInitialImage As String, _
ByVal sResizedImage As String, _
ByVal lMaximumWidth As Long, _
ByVal lMaximumHeight As Long, _
Optional ByVal bPreserveAspectRatio As Boolean = False, _
Optional ByVal bOverwrite As Boolean = False) As Boolean
End Function
< 使用 Excel:Excel2021、使用 OS:Windows11 >
ちょっと勘違いした回答を書いてしまったので、消しました。 すみません (´・ω・`) 2024/03/30(土) 12:24:19
こちらの手法も手詰まりです。
Sub ResizeJPEGFilesToSquare()
Dim FolderPath As String
Dim FileName As String
Dim NewWidth As Double
Dim NewHeight As Double
Dim OriginalWidth As Double
Dim OriginalHeight As Double
Dim AspectRatio As Double
Dim NewFilePath As String
Dim OriginalFilePath As String
Dim FileSystem As Object
Dim FileObject As Object
' 指定フォルダーのパス
FolderPath = "C:\Users\mido\"
' FileSystemオブジェクトを作成
'VBEのツールから参照設定で、Microsoft Scripting Runtimeにチェックを入れてください。
Set FileSystem = CreateObject("Scripting.FileSystemObject")
' 指定フォルダー内のファイルを処理
For Each FileObject In FileSystem.GetFolder(FolderPath).Files
If LCase(FileSystem.GetExtensionName(FileObject.Path)) = "jpg" Then
' オリジナルファイルのパス
OriginalFilePath = FileObject.Path
' 新しいファイル名(同名+_Squareで保存)
NewFilePath = FolderPath & FileSystem.GetBaseName(OriginalFilePath) & "_Square.jpg"
' オリジナル画像のサイズを取得
With CreateObject("WIA.ImageFile")
.LoadFile OriginalFilePath
OriginalWidth = .Width
OriginalHeight = .Height
End With
' 正方形のサイズを計算
AspectRatio = (OriginalWidth + OriginalHeight) / 2
NewWidth = AspectRatio
NewHeight = AspectRatio
' 画像を正方形にリサイズして保存
'使う前の準備として、先にVBAエディタからツール⇒参照設定
'⇒Microsoft Windows Image Acquisition Libraly 2.0 にチェック入れてください
With CreateObject("WIA.ImageProcess")
.Filters.Add .FilterInfos("Scale").FilterID
.Filters(1).Properties("MaximumWidth") = NewWidth
.Filters(1).Properties("MaximumHeight") = NewHeight
.Filters(1).Properties("PreserveAspectRatio") = False
.ApplyToFile OriginalFilePath, NewFilePath
End With
End If
Next FileObject
' メッセージボックスを表示
MsgBox "処理が完了しました。"
End Sub
(Muse) 2024/03/30(土) 16:14:38
マジレスすべきなのかどうなのか悩ましい... と思って傍観してました。^^;
> 以下を試して見ましたが変化がありません。 については、 ホントに Function WIA_ResizeImage の中身が無い状態で試してるんなら、 変化が無くて当然ですよね? (これで変化したらある意味ホラー...)
たぶん最低限↓これくらいは書かないと何もならないでしょう。
Public Function WIA_ResizeImage(ByVal sInitialImage As String, _
ByVal sResizedImage As String, _
ByVal lMaximumWidth As Long, _
ByVal lMaximumHeight As Long, _
Optional ByVal bPreserveAspectRatio As Boolean = False, _
Optional ByVal bOverwrite As Boolean = False) As Boolean
Dim oWIA As Object 'WIA.ImageFile
Dim oIP As Object 'ImageProcess
Set oWIA = CreateObject("WIA.ImageFile")
Set oIP = CreateObject("WIA.ImageProcess")
oIP.Filters.Add oIP.FilterInfos("Scale").FilterID
oIP.Filters(1).Properties("MaximumWidth") = lMaximumWidth
oIP.Filters(1).Properties("MaximumHeight") = lMaximumHeight
oIP.Filters(1).Properties("PreserveAspectRatio") = bPreserveAspectRatio
oWIA.LoadFile sInitialImage
Set oWIA = oIP.Apply(oWIA)
If bOverwrite Then
On Error Resume Next
Kill sResizedImage
On Error GoTo 0
End If
oWIA.SaveFile sResizedImage
WIA_ResizeImage = True
End Function
で、その上で、
> Call WIA_ResizeImage(filePath, filePath, newWidth, newHeight, True, True)
↑ココ
名前付き引数の名前から察するに、この場合「False」だと思います。
(白茶) 2024/03/30(土) 16:50:07
Function WIA_ResizeImageの中身が無いので何も処理しないでリターンしていたのですね。
ホラーだと言われて当然です。
Functionを変更してうまく処理できました。
(Call文のパラメーターもFALSEに書き換えました。)
(Muse) 2024/03/30(土) 17:54:26
「別のアプローチ」の方もちょっと見てみました。
Sub ResizeJPEGFilesToSquare()
Dim FolderPath As String
Dim FileName As String
Dim NewWidth As Double
Dim NewHeight As Double
Dim OriginalWidth As Double
Dim OriginalHeight As Double
Dim AspectRatio As Double
Dim NewFilePath As String
Dim OriginalFilePath As String
Dim FileSystem As Object
Dim FileObject As Object
Dim o As Object '◆追加
' 指定フォルダーのパス
FolderPath = "C:\Users\mido\"
' FileSystemオブジェクトを作成
'VBEのツールから参照設定で、Microsoft Scripting Runtimeにチェックを入れてください。
Set FileSystem = CreateObject("Scripting.FileSystemObject")
' 指定フォルダー内のファイルを処理
For Each FileObject In FileSystem.GetFolder(FolderPath).Files
If LCase(FileSystem.GetExtensionName(FileObject.Path)) = "jpg" Then
' オリジナルファイルのパス
OriginalFilePath = FileObject.Path
' 新しいファイル名(同名+_Squareで保存)
NewFilePath = FolderPath & FileSystem.GetBaseName(OriginalFilePath) & "_Square.jpg"
' オリジナル画像のサイズを取得
Set o = CreateObject("WIA.ImageFile") '◆追加
With o 'CreateObject("WIA.ImageFile") '■書替
.LoadFile OriginalFilePath
OriginalWidth = .Width
OriginalHeight = .Height
End With
' 正方形のサイズを計算
AspectRatio = (OriginalWidth + OriginalHeight) / 2
NewWidth = AspectRatio
NewHeight = AspectRatio
' 画像を正方形にリサイズして保存
'使う前の準備として、先にVBAエディタからツール⇒参照設定
'⇒Microsoft Windows Image Acquisition Libraly 2.0 にチェック入れてください
With CreateObject("WIA.ImageProcess")
.Filters.Add .FilterInfos("Scale").FilterID
.Filters(1).Properties("MaximumWidth") = NewWidth
.Filters(1).Properties("MaximumHeight") = NewHeight
.Filters(1).Properties("PreserveAspectRatio") = False
'.ApplyToFile OriginalFilePath, NewFilePath '■削除
.Apply(o).SaveFile NewFilePath '◆追加
End With
End If
Next FileObject
' メッセージボックスを表示
MsgBox "処理が完了しました。"
End Sub
(白茶) 2024/03/30(土) 17:56:01
ついでに。^^;
私自身「Windows Image Acquisition」ってのは全く存じ上げなかったモノで今回初めて使ってみました。 いい機会を与えて頂き勉強になりました。ありがとうございます。
でまぁお礼というか ここ最近「GDI+ フラット API」について手探り勉強中で、自分的にタイムリーなネタだったので、ちょっと別案書いてみました。 ネットのアチコチからコピってきてペッペして整えただけですけどね。ご笑納くださいwww
Option Explicit
#If False Then
Dim InterpolationMode
Const InterpolationModeInvalid = -1
Const InterpolationModeDefault = 0&
Const InterpolationModeLowQuality = 1&
Const InterpolationModeHighQuality = 2&
Const InterpolationModeBilinear = 3&
Const InterpolationModeBicubic = 4&
Const InterpolationModeNearestNeighbor = 5&
Const InterpolationModeHighQualityBilinear = 6&
Const InterpolationModeHighQualityBicubic = 7&
#End If
Private Type GdiplusStartupInput
GdiplusVersion As Long
DebugEventCallback As LongPtr
SuppressBackgroundThread As Long
SuppressExternalCodecs As Long
End Type
Private Declare PtrSafe Function GdiplusStartup Lib "gdiplus" (ByRef token As LongPtr, ByRef inputbuf As GdiplusStartupInput, Optional ByVal outputbuf As LongPtr = 0) As Long
Private Declare PtrSafe Function GdiplusShutdown Lib "gdiplus" (ByVal token As LongPtr) As Long
Private Declare PtrSafe Function GdipLoadImageFromFile Lib "gdiplus" (ByVal FileName As LongPtr, ByRef image As LongPtr) As Long
Private Declare PtrSafe Function GdipDisposeImage Lib "gdiplus" (ByVal image As LongPtr) As Long
Private Declare PtrSafe Function GdipGetImageHeight Lib "gdiplus" (ByVal image As LongPtr, ByRef Height As Long) As Long
Private Declare PtrSafe Function GdipGetImageWidth Lib "gdiplus" (ByVal image As LongPtr, ByRef Width As Long) As Long
Private Declare PtrSafe Function GdipGetImageGraphicsContext Lib "gdiplus" (ByVal image As LongPtr, graphics As LongPtr) As Long
Private Declare PtrSafe Function GdipDrawImageRectI Lib "gdiplus.dll" (ByVal GpGraphics As LongPtr, ByVal GpImage As LongPtr, ByVal Left As Long, ByVal Top As Long, ByVal Width As Long, ByVal Height As Long) As Long
Private Declare PtrSafe Function GdipDeleteGraphics Lib "gdiplus" (ByVal graphics As LongPtr) As Long
Private Declare PtrSafe Function GdipCreateBitmapFromGraphics Lib "gdiplus" (ByVal Width As Long, ByVal Height As Long, ByVal graphics As LongPtr, bitmap As LongPtr) As Long
Private Enum InterpolationMode 'イメージをスケーリングまたは回転するときに使用されるアルゴリズムを指定します
InterpolationModeInvalid = -1 '内部的に使用される
InterpolationModeDefault = 0& '既定の補間モードを指定します。
InterpolationModeLowQuality = 1& '低品質モードを指定します。
InterpolationModeHighQuality = 2& '高品質モードを指定します。
InterpolationModeBilinear = 3& '双一次補間を指定します。 事前フィルター処理は実行されません。このモードは、イメージを元のサイズの 50% 以下にするような縮小処理には適していません。
InterpolationModeBicubic = 4& '双三次補間を指定します。 事前フィルター処理は実行されません。このモードは、イメージを元のサイズの 25% 以下にするような縮小処理には適していません。
InterpolationModeNearestNeighbor = 5& '最近傍補間を指定します。
InterpolationModeHighQualityBilinear = 6& '高品質双一次補間を指定します。 事前フィルター処理が適用され、高品質の縮小処理が実行されます。
InterpolationModeHighQualityBicubic = 7& '高品質双三次補間を指定します。 事前フィルター処理が適用され、高品質の縮小処理が実行されます。 このモードを使用すると、変換後のイメージが高品質になります。
End Enum
Private Declare PtrSafe Function GdipSetInterpolationMode Lib "gdiplus" (ByVal graphics As LongPtr, ByVal nInterpolationMode As InterpolationMode) As Long
Private Type GUID
Data1 As Long
Data2 As Integer
Data3 As Integer
Data4(7) As Byte
End Type
Private Type EncoderParameter
GUID As GUID
NumberOfValues As Long
TypeAPI As Long
Value As LongPtr
End Type
Private Type EncoderParameters
Count As Long
Parameter(0 To 15) As EncoderParameter
End Type
Private Declare PtrSafe Function CLSIDFromString Lib "ole32" (ByVal lpsz As Any, ByRef pCLSID As GUID) As Long
Private Const CLSID_BMP As String = "{557CF400-1A04-11D3-9A73-0000F81EF32E}"
Private Const CLSID_GIF As String = "{557CF402-1A04-11D3-9A73-0000F81EF32E}"
Private Const CLSID_TIF As String = "{557CF405-1A04-11D3-9A73-0000F81EF32E}"
Private Const CLSID_PNG As String = "{557CF406-1A04-11D3-9A73-0000F81EF32E}"
Private Const CLSID_JPG As String = "{557CF401-1A04-11D3-9A73-0000F81EF32E}"
Private Const QUALITY_PARAMS As String = "{1D5BE4B5-FA4A-452D-9CDD-5DB35105E7EB}"
Private Declare PtrSafe Function GdipSaveImageToFile Lib "gdiplus" (ByVal image As LongPtr, ByVal FileName As LongPtr, ByRef clsidEncoder As GUID, encoderParams As Any) As Long
Private Sub SaveToFile(hImg As LongPtr, FileName As String, Optional ByVal jpgQuarity As Long = 85)
Dim fGUID As GUID, p As EncoderParameters
Select Case UCase$(CreateObject("Scripting.FilesystemObject").GetExtensionName(FileName))
Case "JPG"
Call CLSIDFromString(StrPtr(CLSID_JPG), fGUID)
If jpgQuarity > 100 Then jpgQuarity = 100
If jpgQuarity < 1 Then jpgQuarity = 85
p.Count = 1
With p.Parameter(0)
Call CLSIDFromString(StrPtr(QUALITY_PARAMS), .GUID)
.TypeAPI = 4
.NumberOfValues = 1
.Value = VarPtr(jpgQuarity)
End With
Case "TIF": Call CLSIDFromString(StrPtr(CLSID_TIF), fGUID)
Case "GIF": Call CLSIDFromString(StrPtr(CLSID_GIF), fGUID)
Case "BMP": Call CLSIDFromString(StrPtr(CLSID_BMP), fGUID)
Case Else: Call CLSIDFromString(StrPtr(CLSID_PNG), fGUID)
End Select
If p.Count Then
Call GdipSaveImageToFile(hImg, StrPtr(FileName), fGUID, p)
Else
Call GdipSaveImageToFile(hImg, StrPtr(FileName), fGUID, ByVal 0&)
End If
End Sub
Private Function NumberedFilename(FileName As String, Optional Prefix As String, Optional Suffix As String) As String
Dim i As Long, p As String, b As String, e As String, fn As String
With CreateObject("Scripting.FilesystemObject")
p = .GetParentFolderName(FileName)
b = Prefix & .GetBaseName(FileName) & Suffix
e = .GetExtensionName(FileName)
fn = b & "." & e
i = 1
Do
NumberedFilename = .BuildPath(p, fn)
If Not .FileExists(NumberedFilename) Then Exit Do
i = i + 1
fn = b & Format$(i, " (0).") & e
Loop
End With
End Function
Private Function CreateResizedImage(hSrc As LongPtr, sizeW As Long, sizeH As Long) As LongPtr
Dim w As Long, h As Long, rtn As Long, hGrap As LongPtr, hRes As LongPtr
rtn = GdipGetImageWidth(hSrc, w)
rtn = GdipGetImageHeight(hSrc, h)
If w * h = 0 Then Exit Function
rtn = GdipGetImageGraphicsContext(hSrc, hGrap)
If rtn = 0 Then rtn = GdipCreateBitmapFromGraphics(sizeW, sizeH, hGrap, hRes)
If rtn = 0 Then rtn = GdipDeleteGraphics(hGrap)
If rtn = 0 Then rtn = GdipGetImageGraphicsContext(hRes, hGrap)
If rtn = 0 Then rtn = GdipSetInterpolationMode(hGrap, InterpolationModeBicubic)
If rtn = 0 Then rtn = GdipDrawImageRectI(hGrap, hSrc, 0, 0, sizeW, sizeH)
If rtn = 0 Then CreateResizedImage = hRes
If rtn = 0 Then rtn = GdipDeleteGraphics(hGrap)
End Function
Rem ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sub RESIZETEST2()
Dim FolderPath As String
Dim FileName As String
Dim filePath As String
Dim NewWidth As Long
Dim NewHeight As Long
Dim tkn As LongPtr, gi As GdiplusStartupInput
Dim hImg As LongPtr, hResized As LongPtr
gi.GdiplusVersion = 1&
Call GdiplusStartup(tkn, gi)
FolderPath = "C:\Users\mido\"
FileName = Dir(FolderPath & "*.jpg")
While FileName <> ""
filePath = FolderPath & FileName
If GdipLoadImageFromFile(StrPtr(filePath), hImg) = 0 Then
Call GdipGetImageWidth(hImg, NewWidth)
Call GdipGetImageHeight(hImg, NewHeight)
NewWidth = (NewWidth + NewHeight) \ 2
hResized = CreateResizedImage(hImg, NewWidth, NewWidth)
If hResized Then
Call SaveToFile(hResized, NumberedFilename(filePath, , "_Square"))
Call GdipDisposeImage(hResized)
End If
Call GdipDisposeImage(hImg)
End If
FileName = Dir()
Wend
Call GdiplusShutdown(tkn)
End Sub
(白茶) 2024/03/30(土) 18:27:10
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.