2025/12/06

QR コードの作画:#8)BMP → GIF 変換

前回は、DXL はビットマップファイルに対応していないと(個人的に)衝撃的な事実を知ったことを紹介しました。せっかく作ったライブラリを何とか使いたいので、GIF ファイルに変換して利用したいと思います。

こういった汎用的なコンバート処理は、AI に聞きながら開発すると効率的ですよね。そこで、今回は ChatGPT 先生に相談しながら作業することにします。


BMP → GIF 変換

WIA(Windows Image Acquisition)を使うなどいくつかの方法を提案してくれましたが、64 ビット版の Notes でも動作させたいので、今回は PowerShell を利用して実現することにします。次のコマンドを実行すればよいそうです。

Add-Type -AssemblyName System.Drawing
$bmp = [System.Drawing.Bitmap]::FromFile('C:\tmp\BMP.bmp')
$bmp.Save('C:\tmp\BMP.gif', [System.Drawing.Imaging.ImageFormat]::Gif)

各行は、

  1. .NET の System.Drawing 名前空間を PowerShell セッションにロードします。
    (System.Drawing は Bitmap や Image、ImageFormat の定義を含むライブラリ)
  2. 指定した BMP ファイルを読み込み、System.Drawing.Bitmap オブジェクト(ビットマップ画像を表す .NET オブジェクト)を作成して $bmp に代入
  3. $bmp に保持されている画像を、指定したパスに GIF 形式で保存

となっているそうです。


LotusScript で関数化

教えてもらった PowerShell のコマンドを実行する LotusScript の関数の作成も依頼してみます。頼んでないのに複数ファイルを一括変換してみたり、Domino Designer に貼り付けると文法エラーになったりと、少々回り道をしましたが、何とか完成しました。

完成に向けていくつか要望を出してみたのですが、それぞれ叶えてくれました。

PowerShell 実行ウィンドウの非表示 非表示で WSH を起動し、PowerShell を実行させる
全角対応UTF-8 で PowerShell スクリプトを保存
これによりパスやフォルダ名に日本語(全角文字)が含まれても安全に動作

出来上がった関数は以下の通りです。ChatGPT が出力した関数を不要な部分を削除し、命名規則を整えたバージョンです。

Private Function xConvertBMPtoGIF_PS(ByVal vsFP_BMP As String, ByVal vsFP_GIF As String) As Boolean
   Dim oFSO As Variant
   Dim oShell As Variant
   Dim sPS_FP As String
   Dim sPS As String
   Dim sCMD As String
   Dim sCRLF As String

   ' 初期化
   On Error GoTo ErrorHandler

   xConvertBMPtoGIF_PS = False
   sCRLF = Chr(13) & Chr(10)

   ' 変換元ファイルの存在チェック
   Set oFSO = CreateObject("Scripting.FileSystemObject")
   If Not oFSO.FileExists(vsFP_BMP) Then Exit Function

   ' PowerShell スクリプトの作成
   sPS_FP = Environ$("TEMP") & "\convert_bmp_to_gif.ps1"

   ' PowerShellスクリプト内容(全角パス対応)
   sPS = "Add-Type -AssemblyName System.Drawing"
   sPS = sPS & sCRLF & "$src = '" & Replace(vsFP_BMP, "'", "''") & "'"
   sPS = sPS & sCRLF & "$dst = '" & Replace(vsFP_GIF, "'", "''") & "'"
   sPS = sPS & sCRLF & "$bmp = [System.Drawing.Bitmap]::FromFile($src)"
   sPS = sPS & sCRLF & "$bmp.Save($dst, [System.Drawing.Imaging.ImageFormat]::Gif)"
   sPS = sPS & sCRLF & "$bmp.Dispose()"

   ' UTF-8で.ps1を書き出し(全角対応のため)
   Call xWriteUtf8File(sPS_FP, sPS)

   ' PowerShell実行
   Set oShell = CreateObject("WScript.Shell")
   sCMD = |powershell -NoProfile -ExecutionPolicy Bypass -File "| & sPS_FP & |"|
   oShell.Run sCMD, 0, True       ' 0=ウィンドウ非表示, True=完了待ち

   ' 結果確認
   If oFSO.FileExists(vsFP_GIF) Then
      xConvertBMPtoGIF_PS = True
   End If

ExitFunc:
   ' 一時ファイル削除
   On Error Resume Next
   oFSO.DeleteFile sPS_FP

   Exit Function

ErrorHandler:
   xConvertBMPtoGIF_PS = False
   Resume ExitFunc
End Function

' UTF-8 (BOMなし) でテキストファイルを書き出し
Private Sub xWriteUtf8File(ByVal vsFP As String, ByVal vsText As String)
   Dim oStream As Variant
   Set oStream = CreateObject("ADODB.Stream")
   With oStream
      .Charset = "UTF-8"
      .Open
      .WriteText vsText
      .SaveToFile vsFP, 2    ' 上書き
      .Close
   End With
End Sub


ライブラリへの組み込み

上記関数を前回までに作成した lsDrawQRcode ライブラリに追加します。

続いて、GIF ファイルを作成するメインルーチンも作成します。ビットマップ作成と上記の関数を実行するだけの単純な構造です。

%REM
QR コードの論理データ(Boolean 型の 2 次元配列)から GIF ファイルを作成します。

◆ 引数
   vabQR Boolean QR コードの論理データ(Boolean 型の 2 次元配列)
   vsFP_GIF String フルパスで指定されたファイル名

◆ 戻り値 Booelan
   ファイルが作成出来れば True
%END REM

Public Function DrawQR_GIF(vabQR As Variant, ByVal vsFP_GIF As String) As Boolean
   Dim sFP_BMP As String

   sFP_BMP = vsFP_GIF & ".bmp"
   If DrawQR_BMP(vabQR, sFP_BMP) Then
      Call xConvertBMPtoGIF_PS(sFP_BMP, vsFP_GIF)

      ' 一時ファイル削除
      On Error Resume Next
      'Kill sFP_BMP
   End If
End Function

なお、一時ファイルであるビットマップは最後に削除するコードを書いています。検証のためコメントアウトしていますが、確認後はコメント解除してください。


動作検証

関数が完成したので動作検証を行います。

前回作成したエージェントをコピペして CreateQRcode_GIF を作成します。画像を作成する部分を今回作成した関数に差し替えます。

         ・・・
      '② GIF ファイルの作成
      Call DrawQR_GIF(abQR, "c:\tmp\QR.gif")
         ・・・

このエージェントを実行するアクションボタンをビューに追加します。

正常に動作すると出力フォルダに GIF ファイルが作成されます。


次回の予定

これで GIF 形式の QR コードが出力できるようになりました。次回の最終回では DXL を使ってこの画像をリッチテキストにインラインで貼り付けるコードを紹介します。


前回 QR コードの作画


0 件のコメント:

コメントを投稿