【VBA×画像処理】ビットマップ画像の上下・左右反転

本ページでは、VBAで読み込んだビットマップ(BMP)画像を内部的に処理し、各ピクセルの配置を操作して上下反転・左右反転を行う方法を解説していきます。上下・左右反転とは、文字通り画像を縦方向または横方向に対して対称に入れ替える処理のことを指します。具体的には、上下反転では画像の最上部と最下部を入れ替え、左右反転では左端と右端を入れ替えます。
本ページではビットマップ(BMP)画像の読み込みと書き出しページで実装したクラスに画像処理を追加していきます。前提の機能となる画像の入出力機能を実装しているため事前に一読ください。
上下・左右反転
上下・左右反転の処理は非常に単純でピクセルのRGB情報を縦もしくは横方向でインデックスを反転させるだけです。式で表すと下記の通りです。(※ここで \( H \) は画像の高さ \( W \) は画像の幅)
\[
\begin{cases}
1.\,\, (y, x) \to (H – 1 – y,\, x) \\
2.\,\, (y, x) \to (y,\, W – 1 – x)
\end{cases}
\]
上下反転だけ行う場合は1.の式を、左右反転だけ行う場合は2.の式を適用することでそれぞれ反転が可能です。両方を適用すれば上下左右反転することも可能です。このように、上下・左右反転はいずれも座標変換による単純なインデックスの入れ替え処理で構成されます。
サンプルコード
以下は画像の上下左右をそれぞれ反転するためのコードです。事前に用意しておいたclsBitmap内に下記コードをコピペすることで利用可能になります。
クラスモジュール (clsBitmapに追記)
'****************************************************************************
'* 画像の上下反転
'****************************************************************************
Public Sub FlipVertical()
Dim rgbDataOrg() As RGBTRIPLE '元画像RGBデータ
Dim rgbDataInv() As RGBTRIPLE '上下反転画像RGBデータ
Dim lHeight As Long
Dim lWidth As Long
Dim lX As Long
Dim lY As Long
'元画像情報を取得
rgbDataOrg = m_rgbImageData
lHeight = UBound(rgbDataOrg, 1) + 1 '配列は0始まりなので+1で補正
lWidth = UBound(rgbDataOrg, 2) + 1 '配列は0始まりなので+1で補正
'配列サイズを定義(元画像と同じ2次元配列)
ReDim rgbDataInv(UBound(rgbDataOrg, 1), UBound(rgbDataOrg, 2))
'上下反転
For lY = 0 To lHeight - 1
For lX = 0 To lWidth - 1
rgbDataInv(lY, lX).rgbRed = rgbDataOrg((lHeight - 1) - lY, lX).rgbRed
rgbDataInv(lY, lX).rgbGreen = rgbDataOrg((lHeight - 1) - lY, lX).rgbGreen
rgbDataInv(lY, lX).rgbBlue = rgbDataOrg((lHeight - 1) - lY, lX).rgbBlue
Next
Next
'RGBデータを更新
m_rgbImageData = rgbDataInv
End Sub
'****************************************************************************
'* 画像の左右反転
'****************************************************************************
Public Sub FlipHorizontal()
Dim rgbDataOrg() As RGBTRIPLE '元画像RGBデータ
Dim rgbDataInv() As RGBTRIPLE '左右反転画像RGBデータ
Dim lHeight As Long
Dim lWidth As Long
Dim lX As Long
Dim lY As Long
'元画像情報を取得
rgbDataOrg = m_rgbImageData
lHeight = UBound(rgbDataOrg, 1) + 1 '配列は0始まりなので+1で補正
lWidth = UBound(rgbDataOrg, 2) + 1 '配列は0始まりなので+1で補正
'配列サイズを定義(元画像と同じ2次元配列)
ReDim rgbDataInv(UBound(rgbDataOrg, 1), UBound(rgbDataOrg, 2))
'左右反転
For lX = 0 To lWidth - 1
For lY = 0 To lHeight - 1
rgbDataInv(lY, lX).rgbRed = rgbDataOrg(lY, (lWidth - 1) - lX).rgbRed
rgbDataInv(lY, lX).rgbGreen = rgbDataOrg(lY, (lWidth - 1) - lX).rgbGreen
rgbDataInv(lY, lX).rgbBlue = rgbDataOrg(lY, (lWidth - 1) - lX).rgbBlue
Next
Next
'RGBデータを更新
m_rgbImageData = rgbDataInv
End Sub
標準モジュール
Option Explicit
Sub main()
Dim sPathBmpSrc As String
Dim sPathBmpExport As String
Dim oBitmap As clsBitmap
sPathBmpSrc = "C:\...\source.bmp"
sPathBmpExport = "C:\...\output.bmp"
Set oBitmap = New clsBitmap
Call oBitmap.LoadBitmap(sPathBmpSrc) '画像読み込み
Call oBitmap.FlipVertical '上下反転
Call oBitmap.FlipHorizontal '左右反転
Call oBitmap.ExportBitmap24(sPathBmpExport) '画像出力
End Sub
使い方は非常にシンプルで上記コードのように既に用意しておいた画像の入出力処理の間に、上下・左右反転処理を呼び出すだけです。他の画像処理と組み合わせることも可能です。
関連情報
VBA×画像処理ページ
次回 >> 画像の回転
前回 >> 画像のネガポジ反転
画像処理のメインページへ戻る
参考
外部リンク:Flipped image – Wikipedia
:Flopped image – Wikipedia













