【CorelDRAW VBA】巨大CDRファイルを劇的に軽量化する「画像再サンプリング」の極意
業務でCorelDRAWを扱っていると、必ず直面する壁がある。それは、「数百MBに膨れ上がったCDRファイル」だ。原因は明確。高解像度のまま配置されたビットマップ画像だ。
「ファイルを開くたびに固まる」「サーバーの容量を圧迫する」「再送時に転送エラーが起きる」。これらは全て、VBAで一掃できる。今日は、単なる「画像圧縮」を超えた、プロダクションレベルの「画像最適化エンジン」の設計思想と実装を伝授する。
—
なぜ「手作業」や「適当なマクロ」ではいけないのか
多くの初心者は、`Bitmap.Resample` メソッドを呼べば終わると思っている。だが、それは甘い。以下の落とし穴を理解していないと、現場で必ず事故が起きる。
1. 非可逆的なメモリ破壊: 大量画像を一度に処理しようとすると、CorelDRAWのメモリ管理が破綻し、`COMException`を吐いて沈黙する。
2. 解像度情報の喪失: 意図しないカラーモード変換や、プロファイル欠落による色味の変化。
3. Undoスタックの肥大化: 最適化処理を一つのUndo単位にしておかないと、保存後に「戻る」が効かなくなるか、メモリを食いつぶす。
我々が目指すべきは、「スタックを汚さず、メモリを解放しながら、確実に軽量化する」という設計だ。
—
実装の核:再サンプリング・エンジン
以下のコードは、ページ内の全てのビットマップを探索し、指定解像度を超えているものだけをインプレースで再サンプリングする堅牢な実装である。
‘ ———————————————————
‘ ビットマップ最適化ルーチン
‘ @param targetDPI 最適化対象のDPI閾値
‘ @param newDPI 目標とするDPI
‘ ———————————————————
Sub OptimizeBitmapsInDocument(Optional targetDPI As Double = 350, Optional newDPI As Double = 300)
Dim sr As ShapeRange
Dim sh As Shape
Dim bmp As Bitmap
‘ ドキュメント全体のビットマップを抽出
Set sr = ActiveDocument.ActivePage.FindShapes(Type:=cdrBitmapShape)
‘ Undoスタックをグループ化(処理終了後、1回の操作で戻せるようにする)
ActiveDocument.BeginCommandGroup “Bitmap Optimization”
On Error GoTo Cleanup ‘ 万が一のクラッシュに備える
For Each sh In sr
Set bmp = sh.Bitmap
‘ 解像度チェック(無駄な再計算を避ける)
If bmp.ResolutionX > targetDPI Then
‘ 再サンプリング実行
‘ ※ColorConversionMode: 既存のプロファイルを維持
bmp.Resample , , newDPI, newDPI, True
End If
Next sh
Cleanup:
ActiveDocument.EndCommandGroup
If Err.Number <> 0 Then MsgBox “最適化中にエラーが発生しました: ” & Err.Description
End Sub
—
実務で「詰まない」ための3つの知見
1. ファイルサイズの「真の軽量化」は保存オプションに宿る
いくら画像を再サンプリングしても、CDRの保存設定がデフォルトのままでは意味がない。保存時に「埋め込み」と「圧縮」のオプションを明示的に制御する必要がある。
‘ 最適化後に軽量で保存するベストプラクティス
Sub SaveOptimizedDocument(path As String)
Dim opt As StructSaveAsOptions
Set opt = CreateStructSaveAsOptions
‘ 圧縮率を最大に設定
opt.Version = cdrVersion14 ‘ 必要に応じた互換性
opt.EmbedVBAProject = False ‘ マクロ不要ならFalseで軽量化
ActiveDocument.SaveAs path, opt
End Sub
2. メモリ管理:大きなファイルは「分割」を検討せよ
ファイルサイズが1GBを超える場合、VBA単体でのループ処理は限界を迎える。その場合は、`Document.ExportBitmap` を活用し、一時的に外部ファイルへ退避させてから再配置する「スワップ処理」を設計に組み込む必要がある。
3. データベース連携時の「整合性」
もしあなたのツールが、管理システム(AccessやSQL Server等)からファイルパスを取得して自動化するタイプなら、以下の点に注意せよ。
- 排他制御: 誰かが編集中ではないか? `On Error Resume Next` でファイルを開こうとし、エラーが返る場合は「他者が使用中」と判定してスキップするロジックを必ず入れること。
—
リーダーからの最後のアドバイス
「自動化」とは、単純作業をプログラムに置き換えることではない。「人間が気付かないところで起きている非効率を、システム的に根絶すること」だ。
今回のコードをベースに、さらに「最適化対象のビットマップがあるかログを出力する機能」や「処理後のファイルサイズ差分を計算して効果を可視化する機能」を追加してみるといい。数値で成果を示せば、周囲の評価は一変するはずだ。
CorelDRAWのポテンシャルを使いこなせ。君のコードが、組織の生産性を左右するのだから。
