【簡単Excelマクロ・VBA】複数の画像ファイルを一括リサイズする|アプリ事例 #001

アフィリエイト広告を利用しています。
QRコード
【QRコード】PC<--->スマホの切り替えにご利用ください
運営者・ポテ

いつもありがとうございます。

ノンプログラマー向け「Excelマクロ・VBAアプリ事例紹介シリーズ」へようこそ。

本稿では、複数の画像ファイルを一括リサイズするアプリを紹介します。

皆さんは、画像ファイルのサイズを小さくしたいときなどはないでしょうか。例えば、Word や PowerPoint に挿入する写真の容量が大きすぎて、ファイルが重くなり動作が遅くなるときなどです。

画像ファイルのリサイズを専用のアプリを使って行う場合、以下のようなデメリットがあります。

  • インストールが必要
    追加のアプリをインストールする必要があります。 ※プリインストールされているものを除く
  • GUI操作が複雑
    GUIはソフトウェアごとに違います。慣れるまでに時間がかかることがあります。
  • カスタマイズができない
    一括操作に対応していないアプリケーションソフトウェアもあります。この場合は、ひとつずつ画像ファイルを操作するしかありません。
  • 有料の場合がある
    アプリによっては有料の場合があります。高価なソフトウェアもあります。

VBAでアプリを作成すると上記のデメリットを解消できます。

  • インストール不要
    Excel がインストールされていれば、追加のソフトウェアをインストールする必要がありません。Excel は大体の PC にインストールされていると思います。
  • 操作が簡単
    自分で作成するアプリですので、操作が簡単になるようにアプリを作成していくことができます。
  • カスタマイズが可能
    自由にカスタマイズが可能です。複数ファイルの一括操作に対応させたり、リサイズ後の画像の命名則を決めたり、扱える画像ファイルの拡張子を増やしたり、その他何でも思いのままです。
  • 無料
    Excelがインストールされていることが前提ですが、自分で作成するアプリですので購入する必要がありません。

VBAで自分に合ったアプリを作成し、仕事量は半分に、成果は2倍にしていきましょう。初心者でも理解がしやすいように、分かりやすく解説していきます。ぜひご覧ください。

ことばの意味

  • ノンプログラマー
    プログラミングを本職としない人たちのことです。
  • マクロ
    VBAを使って作成される「機能」のことです。
  • VBA
    Visusal Basic for Application の略で、プログラミング言語のことです。
  • プリインストール
    PCが出荷される前に、あらかじめアプリがインストールされていることです。


複数の画像ファイルを一括でリサイズするアプリ

基本コード

複数の画像ファイルを一括でリサイズするVBAコードの説明をしていきます。

まず、フォルダ構成、ファイル構成は以下のようになっています。

"リサイズする画像ファイル"には以下の画像ファイルが入っています。

このアプリでは、「画像ファイルをリサイズする.xlsm」にマクロを記述します。そのマクロを動作させると同階層にある「リサイズする画像ファイル」フォルダを見に行き、そこに入っているすべての画像ファイルをリサイズします。

以下にコードを示します。

Sub Sample()

'以下のライブラリの参照設定が必要
'1. Microsoft Scripting Runtime
'2. Microsoft Windows Image Acquisition Library v2.0


'変数の宣言
Dim folder_path As String             ' 画像が保存されているフォルダのパス
Dim fso As Scripting.FileSystemObject ' ファイル操作を行うためのFileSystemObject
Dim folder As folder                  ' 指定したフォルダのオブジェクト
Dim max_width As Long                 ' リサイズ後の画像の最大幅
Dim max_height As Long                ' リサイズ後の画像の最大高さ
Dim file As file                      ' フォルダ内の各ファイルのオブジェクト
Dim img_object As ImageFile           ' 画像ファイルのオブジェクト
Dim orig_width As Long                ' 画像の元の幅
Dim orig_height As Long               ' 画像の元の高さ
Dim new_width As Long                 ' リサイズ後の画像の幅
Dim new_height As Long                ' リサイズ後の画像の高さ
Dim ratio As Double                   ' リサイズ比率
Dim img_processor As ImageProcess     ' 画像処理を行うためのオブジェクト
Dim new_file_path As String           ' リサイズ後の画像の新しいファイルパス
Dim base_name As String               ' 元のファイル名(拡張子を除く)
Dim extension As String               ' ファイルの拡張子
Dim hasFile As Boolean                ' フォルダに画像ファイルが存在するかどうかのフラグ



'画像ファイルが保存されているフォルダのパスを指定
folder_path = ThisWorkbook.Path & "\リサイズする画像ファイル"    ' ここに実際のフォルダのパスを指定する


'FileSystemObject のインスタンスを作成
Set fso = New FileSystemObject


'指定したフォルダのインスタンスを作成
Set folder = fso.GetFolder(folder_path)


'画像の最大幅を設定
max_width = 400


'画像の最大高さを設定
max_height = 400


'フォルダ内に画像ファイルがひとつもない場合の処理
hasFile = False


'フォルダ内の全ファイルに対するループ処理
For Each file In folder.Files
    
    '対象1ファイルの拡張子が画像形式の場合のみ処理
    If LCase(Right(file.Name, 3)) = "png" Or LCase(Right(file.Name, 3)) = "jpg" Or LCase(Right(file.Name, 4)) = "jpeg" Then
    
        hasFile = True
        
        '画像ファイルオブジェクトを作成
        Set img_object = New ImageFile
        img_object.LoadFile file.Path
        
        ' 画像の元の幅と高さを取得
        orig_width = img_object.Width
        orig_height = img_object.Height
        
        'リサイズ比率を計算
        ratio = Application.WorksheetFunction.Min(max_width / orig_width, max_height / orig_height)
        
        '新しい幅と高さを設定
        new_width = orig_width * ratio
        new_height = orig_height * ratio
        
        ' 画像処理オブジェクトを作成し、リサイズ用のScaleフィルタを追加
        Set img_processor = New ImageProcess
        img_processor.Filters.Add img_processor.FilterInfos("Scale").FilterID
        
        'リサイズのための最大幅と最大高さを設定
        img_processor.Filters(1).Properties("MaximumWidth").Value = new_width
        img_processor.Filters(1).Properties("MaximumHeight").Value = new_height
        
        'リサイズを適用して新しい画像オブジェクトを取得
        Set img_object = img_processor.Apply(img_object)
        
        '新しいファイル名を作成
        base_name = Left(file.Name, Len(file.Name) - Len(fso.GetExtensionName(file.Name)) - 1)
        extension = fso.GetExtensionName(file.Name)
        new_file_path = folder_path & "\" & base_name & "_resized." & extension
        
        '新しいファイル名が既に存在するか確認
        If fso.FileExists(new_file_path) Then
            
            '警告メッセージを表示して処理をスキップ
            MsgBox "ファイル" & base_name & "_resized." & extension & " は既に存在します。処理をスキップします。"
            
        Else
            
            'リサイズされた画像を新しいファイル名で保存
            img_object.SaveFile new_file_path
            
        End If
        
    End If

Next file

If Not hasFile Then

    MsgBox "フォルダに画像ファイルが見つかりませんでした。処理を中断します。", vbExclamation

End If

    
' 処理が完了した際のメッセージボックス
MsgBox "リサイズが完了しました。ご利用ありがとうございました。", vbInformation

End Sub

このコードを実行すると以下のようになります。

まず処理が完了すると、処理が完了したことを知らせるメッセージボックスが表示されます。

「リサイズする画像ファイル」フォルダ内に、リサイズされた画像ファイルが出力されています。リサイズされた画像ファイルは、ファイル名の末尾が "_resized" になっています。サイズの列を見ると、ファイルのサイズが小さくなっており、リサイズされていることが分かります。尚、この処理にかかる時間は数秒です。非常に高速です。

マクロ実行結果

では解説をしていきます。

'以下のライブラリの参照設定が必要
'1. Microsoft Scripting Runtime
'2. Microsoft Windows Image Acquisition Library v2.0

これはコードの一部ではありませんが、このマクロを実行するために必要なライブラリをコメントとして記載しています。

このコードでは、ファイル操作のための Microsoft Scripting Runtime と、画像処理のための Microsoft Windows Image Acquisition Library v2.0 という2つのライブラリが必要です。これらを参照設定することで、VBAで高度なファイル操作や画像処理が可能になります。

尚、ライブラリとは特定の機能をもったコードの集合体です。ソフトウェア作成における部品のようなものです。新しいアプリケーションを作成する際、ライブラリを使用することで、プログラマーは複雑なコードを自分で書く必要がなくなります。

これらのライブラリは、事前に参照設定に追加しておく必要があります。一度設定すれば、次回以降は再設定する必要はありません。以下の手順で実施してください。

VBE画面から「ツール」--> 「参照設定」を開きます。

Microsoft Scripting Runtime と Microsoft Windows Image Acquisition Library v2.0 にチェックを入れて「OK」を押します。以上で終了です。尚、これらのライブラリを初めて設定する場合、上位には表示されていません。アルファベット順に従ってリストの下の方に表示されていますので、慌てずに探してください。

'変数の宣言
Dim folder_path As String             ' 画像が保存されているフォルダのパス
Dim fso As Scripting.FileSystemObject ' ファイル操作を行うためのFileSystemObject
Dim folder As folder                  ' 指定したフォルダのオブジェクト
Dim max_width As Long                 ' リサイズ後の画像の最大幅
Dim max_height As Long                ' リサイズ後の画像の最大高さ
Dim file As file                      ' フォルダ内の各ファイルのオブジェクト
Dim img_object As ImageFile           ' 画像ファイルのオブジェクト
Dim orig_width As Long                ' 画像の元の幅
Dim orig_height As Long               ' 画像の元の高さ
Dim new_width As Long                 ' リサイズ後の画像の幅
Dim new_height As Long                ' リサイズ後の画像の高さ
Dim ratio As Double                   ' リサイズ比率
Dim img_processor As ImageProcess     ' 画像処理を行うためのオブジェクト
Dim new_file_path As String           ' リサイズ後の画像の新しいファイルパス
Dim base_name As String               ' 元のファイル名(拡張子を除く)
Dim extension As String               ' ファイルの拡張子
Dim hasFile As Boolean                ' フォルダに画像ファイルが存在するかどうかのフラグ

ここでは、コード内で使用する変数が宣言されています。変数は Dim 変数名 As データ型 の構文で宣言します。これにより、各変数は As 以降で指定したデータ型のデータを格納できるようになります。

例えば、folder_path は画像が保存されているフォルダのパスを格納する変数であり、文字列型(String)のデータを格納できます。尚、各変数の用途については、右端にコメントを記載しています。

'画像ファイルが保存されているフォルダのパスを指定
folder_path = ThisWorkbook.Path & "\リサイズする画像ファイル"    ' ここに実際のフォルダのパスを指定する

ここでは、画像が保存されているフォルダのパスを設定しています。ThisWorkbook.Path は、This Workbook、つまりこのマクロを記述している「画像ファイルをリサイズする.xlsm」自身が保存されているフォルダのパスを表します。

このパスに 「リサイズする画像ファイル」を追加し、画像が保存されているフォルダを「リサイズする画像ファイル」フォルダに設定しています。

'FileSystemObject のインスタンスを作成
Set fso = New FileSystemObject

FileSystemObject のインスタンス(実体)を作成し、そのインスタンスを変数 fso に格納します。インスタンスとは、設計図(プログラミングの世界ではクラスと呼ばれる)に基づいて作成された「実体」のことです。

'指定したフォルダのインスタンスを作成
Set folder = fso.GetFolder(folder_path)

指定したフォルダのパス に基づいて、"フォルダオブジェクト"を取得し、そのオブジェクトを変数 folder に格納します。オブジェクトとは、VBAで操作する対象のことです。変数 folder にフォルダオブジェクトを格納することで、プログラムがそのフォルダを操作できるようになります。

'画像の最大幅を設定
max_width = 400


'画像の最大高さを設定
max_height = 400

ここでは、リサイズ"後"の画像の最大幅と最大高さを指定しています。単位はピクセルです。

'フォルダ内に画像ファイルがひとつもない場合の処理
hasFile = False

この変数 hasFile は、フォルダ内の画像ファイルの存在有無の判定結果を格納するための変数です。初期状態では False (存在しない)に設定しておきます。この変数は後の処理で使用します。

'フォルダ内の全ファイルに対するループ処理
For Each file In folder.Files

フォルダ内のすべてのファイルに対して順次処理を行うループを開始します。For Each file In folder.Files というコードは、フォルダ内の全ファイルを一つずつ取り出し、それぞれのファイルに対して指定された処理を実行することを意味します。各ファイルに対して、以下で説明していく処理が行われます。

    '対象1ファイルの拡張子が画像形式の場合のみ処理
    If LCase(Right(file.Name, 3)) = "png" Or LCase(Right(file.Name, 3)) = "jpg" Or LCase(Right(file.Name, 4)) = "jpeg" Then

ここでは、if文を用いて取得した画像ファイルの拡張子が "png"、"jpg"、"jpeg" のいずれかに一致するかを判定しています。なお、ここで使用している LCase 関数は、指定した文字列内の文字を小文字に変換するための関数です。同じ拡張子であっても ".JPEG" や ".jpg" のように大文字と小文字の違いがある場合があるため、これに対応させています。

        hasFile = True

これは直前の If 文が True だった場合の処理です。変数 hasFile を True に更新しています。初期状態では False でしたが、If文が True だったということは画像ファイルが存在したということであるため、True に更新しています。

        '画像ファイルオブジェクトを作成
        Set img_object = New ImageFile
        img_object.LoadFile file.Path

Set img_object = New ImageFile で新しい ImageFile オブジェクトを作成し、そのオブジェクトを変数 img_object に格納しています。次に、img_object.LoadFile file.PathLoadFile メソッドを呼び出し、file.Path で指定されたファイルパスにある画像ファイルを読み込んでいます。

ここで LoadFile メソッドは、指定されたファイルパスから画像ファイルを読み込み、その画像データをオブジェクトに取り込むためのメソッドです。また、file.Pathfile オブジェクトの Path プロパティのことで、ファイルのフルパスを意味します。

        ' 画像の元の幅と高さを取得
        orig_width = img_object.Width
        orig_height = img_object.Height

元の画像の幅と高さを取得しています。これらの値は、画像をリサイズする際に縦横比を計算するために使用します。リサイズ比率を正しく計算することで、画像が歪むことなく適切なサイズに変更できます。

        'リサイズ比率を計算
        ratio = Application.WorksheetFunction.Min(max_width / orig_width, max_height / orig_height)

画像のリサイズ比率を計算しています。Application.WorksheetFunction.Min 関数は、括弧内の複数の値のうち、最小の値を返します。ここでは、幅と高さのリサイズ比率のうち、小さいほうの値を変数 ratio に格納しています。

尚、WorksheerFunction は、Excelのワークシートで使える関数をVBAで使用するための機能です。これにより Excel で一般的につかる数式や関数(例えば、Min や SUMなど)をVBAのコード内で呼び出して使うことが出来ます。

        '新しい幅と高さを設定
        new_width = orig_width * ratio
        new_height = orig_height * ratio

元画像のサイズに上述のリサイズ比率を乗じて、新しい幅と高さをそれぞれ変数 new_width 及び new_height に格納しています。

        ' 画像処理オブジェクトを作成し、リサイズ用のScaleフィルタを追加
        Set img_processor = New ImageProcess
        img_processor.Filters.Add img_processor.FilterInfos("Scale").FilterIz

ここでは、画像のリサイズを行うためのオブジェクトを作成し、そのオブジェクトに画像のサイズを変更するためのフィルタを設定しています。

77行目の Set img_processor = New ImageProcess で ImageProcess クラスの新しいインスタンスを作成しています。このオブジェクトは、画像の処理(フィルタの適用など)を行うために使用されます。

78行目の img_processor.Filters.Add img_processor.FilterInfos("Scale").FilterID は、ImageProcess オブジェクトの Filters コレクションに Scale フィルタを追加しています。.FilterInfos("Scale").FilterID のところで、Scale フィルタの識別子(ID)を取得しています。このフィルタは画像のサイズを変更するためのフィルタです。

        'リサイズのための最大幅と最大高さを設定
        img_processor.Filters(1).Properties("MaximumWidth").Value = new_width
        img_processor.Filters(1).Properties("MaximumHeight").Value = new_height

ここでは、Scale フィルタのプロパティを設定しています。Filters(1) は上述のフィルタの追加で設定した Scale フィルタを指しています。

Scale フィルタの MaximumWidthMaximumHeight プロパティにそれぞれ上述の変数 new_widthnew_height を設定することで、画像の幅と高さを設定しています。

        'リサイズを適用して新しい画像オブジェクトを取得
        Set img_object = img_processor.Apply(img_object)

右側の img_processor.Apply(img_object) は、img_processor に設定されたフィルタ(この場合は Scale フィルタ)を img_object に適用しています。つまり、img_object をリサイズしています。

これを Set 文を用いて変数 img_object に格納しています。つまり、img_object を更新しています。

        '新しいファイル名を作成
        base_name = Left(file.Name, Len(file.Name) - Len(fso.GetExtensionName(file.Name)) - 1)
        extension = fso.GetExtensionName(file.Name)
        new_file_path = folder_path & "\" & base_name & "_resized." & extension

ここでは、リサイズした画像に新しい名前を付けて出力するための準備を行っています。

88行目は、元のファイル名から拡張子を除いた部分を取得し、それを変数 base_name に格納しています。89行目は、ファイルの拡張子を取得して変数 extension に格納します。90行目は、フォルダのパス、変数 base_name、文字列 _resized、変数 extension を結合して、新しいファイルパスの変数 new_file_path を作成しています。

        '新しいファイル名が既に存在するか確認
        If fso.FileExists(new_file_path) Then
            
            '警告メッセージを表示して処理をスキップ
            MsgBox "ファイル" & base_name & "_resized." & extension & " は既に存在します。処理をスキップします。"
            
        Else
            
            'リサイズされた画像を新しいファイル名で保存
            img_object.SaveFile new_file_path
            
        End If

ここでは、新しいファイル名が既に存在するかどうかを確認し、存在する場合は警告メッセージを表示して処理をスキップし、存在しない場合はリサイズされた画像を保存するためのものです。

まず、fso.FileExists(new_file_path) を使って、新しいファイルパス new_file_path が既に存在するかどうかを確認します。もし存在する場合は、MsgBox を使って警告メッセージを表示し、処理をスキップします。

一方、新しいファイルパスが存在しない場合は、img_object.SaveFile new_file_path を使って、リサイズされた画像を新しいファイル名で保存します。これにより、リサイズされた画像が指定されたフォルダに保存されます。

Next file

このコードは、For each Next ループ内の処理が完了した後、次のファイルに対して同じ処理を繰り返すことを指示しています。

If Not hasFile Then

    MsgBox "フォルダに画像ファイルが見つかりませんでした。処理を中断します。", vbExclamation

End If

ここでは、フォルダ内に画像ファイルが存在しない場合の処理を行っています。

If Not hasFile Then で、hasFile 変数が False の場合、つまりフォルダ内に画像ファイルが見つからなかった場合、メッセージボックスを表示してユーザーに画像ファイルが見つからなかったことを知らせています。hasFile が False の場合、リサイズ処理は行われません。

' 処理が完了した際のメッセージボックス
MsgBox "リサイズが完了しました。ご利用ありがとうございました。", vbInformation

ここでは、マクロが完了したことをユーザーに通知するためのメッセージボックスを表示しています。

以上で解説は終わりです。

アプリ化して配布する方法

上述のコードでは、画像のサイズ指定をコードの中で行っていました。この部分です。

'画像の最大幅を設定
max_width = 400


'画像の最大高さを設定
max_height = 400

コード上の問題はありませんが、これではサイズがコード内で決まっていますので、自分以外のユーザーが使うには大変不便です。プログラミングをご存じない方にとっては、サイズを変更することはほぼ不可能でしょう。

そこで、画像のサイズ指定の部分を Excel のワークシート内でできるようにして、誰でも任意のリサイズができるようにしたいと思います。

Excel に以下のようなワークシートを作成します。

「リサイズ実行」のボタンには、クリックするとマクロが動くようにマクロを「登録」しておきます。

ボタン上で右クリック --> 「マクロの登録」をクリックします。

登録したいマクロを選択してOKをクリックします。本稿では、Sample2 というマクロが該当しますが、ここは皆さんのマクロに応じて対応してください。

このようにしておくと、ボタンをクリックしただけで登録したマクロが作動します。

次に、コードのこの部分を、

'画像の最大幅を設定
max_width = 400


'画像の最大高さを設定
max_height = 400

以下のように書き換えます。

'画像の最大幅を設定
max_width = ThisWorkbook.Worksheets(1).Cells(10, 4).Value


'画像の最大高さを設定
max_height = ThisWorkbook.Worksheets(1).Cells(11, 4).Value

これで、ワークシートの使用手順2で設定したサイズに画像がリサイズされます。

このようにExcelのシートの使用手順2の画像サイズの値を変更するだけで、リサイズする画像サイズを変更することができます。

つまり、コードを意識することなく、誰でも任意のサイズに画像をリサイズすることができます。

このようなアプリをサッと作成してコミュニティに配布することができれば、生産性向上に大いに役立つでしょう。

おわりに

運営者・ポテ

ご覧いただきありがとうございました。

本稿では、複数の画像ファイルを一括リサイズするアプリを紹介しました。

お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。

皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。

なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。


筆者の記事関連経験

  • VBA使用経験約20年
    実務に使用するマクロを多数作成してきました。
  • Python 3 エンジニア認定基礎試験
    経済産業省が定めたガイドライン「ITスキル標準(ITSS)」に掲載されている民間資格です。

VBAプログラミングスキルアップのための参考情報

ここでは参考図書を紹介いたしますが、これらに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心よりお祈りしております。

VBAプログラミングのスキルアップ

学習用としてもハンドブックとしても役立つ便利な書籍がこちらです。価格はやや高めですが、その内容は非常に充実しています。相応のスキルを身に付けるためには、こうしたしっかりとした書籍を一冊持っておくと良いでしょう。



入門書に関しては、どの書籍も大きな違いはありません。あまり迷うことに時間をかけるよりは、手頃なものを一冊選んでみると良いでしょう。VBAの入門書は数多く出版されていますので、興味がある方はぜひチェックしてみてください。

甲乙つけがたい場合、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。

\チェックしてみよう/

\チェックしてみよう/

\チェックしてみよう/


VBAのプログラミング能力を客観的に証明したい場合には「VBAエキスパート試験」があります。この試験はVBAの知識を公式に認定するものです。VBAの総合的な能力獲得を目指す方に適しています。以下の公式テキストが販売されております。



プログラミングの一般教養

「独学プログラマー」というプログラミングの魅力を解説した書籍があります。これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。


こちらの記事でも紹介しております。もしよろしければご覧ください。

QRコード
【QRコード】PC<--->スマホの切り替えにご利用ください

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です