前回、前々回で使用した自作プログラムは以下の通り。
構造はExcel VBAで起動して元画像をBMPで読み取り、
Cのdllに画像データと量子化係数を引き渡して
dllでYCbCr変換→DCT変換→量子化→逆DCT変換→RGB変換してVBAに戻し
VBAで結果をBMPファイル化して保存するもの。
ハフマン・ランレングス変換とJpegファイル化はしていない。
ハフマン・ランレングス変換の可逆性は保証されているし、プログラムは複雑そうだし・・・
(あくまでも、どんなパラメータでJpeg化・再生表示させたら、どんな画像になるかの実験用のオアソビProgっす)
また、量子化係数テーブルをIJGの推奨ルールで作成する部分はExcelのワークシート関数で作成している。
(ワークシート関数は下画像の一番上:=IF(INT(・・・部分を参照)
Excelワークシートは以下のようにして、変換パラメータ等をVBAに読み取らせている。
ではまずVBAプログラムから・・・
(なお、CのdllはSim_JPG.dll名でCドライブのルートに置く前提なので、
それがイヤなヒトは青文字部分を適宜変更するように。
また、16x16pix単位で処理を行うため、変換に与える元BMP画像は
タテ・ヨコともにpix数は16の倍数である必要があります)
'DLL Declaration
Private Declare Function Sim_JPG _
Lib "C:\Sim_JPG.dll" _
(ByRef A As Byte, ByRef B As Byte, ByRef C As Byte, _
ByVal W As Long, ByVal H As Long, ByVal M As Byte, _
ByVal Ad As Byte, ByVal Sp As Byte) _
As Integer
'--------------------------------------------
Private Type BM_Spec 'BMPファイルヘッダ領域
ID_B As Byte
ID_M As Byte
Spec(12) As Long
End Type
'
Private Type BGR 'BMPファイル画像領域(BMPは画素毎にBGR順)
B As Byte
G As Byte
R As Byte
End Type
'
'
Sub S_JPEG()
Dim BM_Head As BM_Spec
Dim Pix_BGR() As BGR
Dim Pix_Width As Long
Dim Pix_Height As Long
Dim QT_Y(7, 7) As Byte
Dim QT_Cbr(7, 7) As Byte
Dim St As Byte
Dim M As Byte
Dim Ad As Byte
Dim Sp As Byte
Dim N As Long
Range("B17") = "Reading Data"
BMP_Folder$ = Range("B2")
BMP_File$ = BMP_Folder$ & Range("B3")
GoSub Read_BMP_H
If BM_Head.ID_B <> &H42 Or BM_Head.ID_M <> &H4D _
Or BM_Head.Spec(3) <> 40 Or BM_Head.Spec(6) <> &H180001 Then
St = 0
GoTo Quit_Prog
End If
Pix_Width = BM_Head.Spec(4)
Pix_Height = BM_Head.Spec(5)
If Pix_Width Mod 16 <> 0 Or Pix_Height Mod 16 <> 0 Then
St = 1
GoTo Quit_Prog
End If
N = Pix_Width * Pix_Height - 1
ReDim Pix_BGR(N)
GoSub Read_BMP_D
GoSub Set_QT
GoSub Sub_S
GoSub CbCr_Adjust
GoSub S_Point
Range("B17") = "Start Transfer"
Ret = Sim_JPG(Pix_BGR(0).B, QT_Y(0, 0), QT_Cbr(0, 0), _
Pix_Width, Pix_Height, M, Ad, Sp)
Range("B17") = "Writing Data"
BMP_File$ = BMP_Folder$ & "Result.BMP"
GoSub Write_BMP
Range("B17") = "Finish!!"
Exit Sub
'------
Write_BMP:
Open BMP_File$ For Binary As #1
Put #1, , BM_Head
Put #1, , Pix_BGR()
Close #1
Return
'------
Read_BMP_H:
Open BMP_File$ For Binary As #1
Get #1, , BM_Head 'BMPヘッダ読み込み
Close #1
Return
'------
Read_BMP_D:
Open BMP_File$ For Binary As #1
Get #1, 55, Pix_BGR() 'BMPデータ読み込み
Close #1
Return
'------
Set_QT:
Range("D2").Select
For i = 0 To 7
For j = 0 To 7
QT_Y(i, j) = Selection.Offset(i, j)
Next j
Next i
Range("D12").Select
For i = 0 To 7
For j = 0 To 7
QT_Cbr(i, j) = Selection.Offset(i, j)
Next j
Next i
Return
'------
Sub_S:
M = Range("B8")
If M < 0 Or 3 < M Then
St = 2
GoTo Quit_Prog
End If
Return
'------
S_Point:
Sp = Range("B10")
If Sp < 0 Or 1 < Sp Then
St = 3
GoTo Quit_Prog
End If
Return
'------
CbCr_Adjust:
Ad = Range("B12")
If Ad < 0 Or 2 < Ad Then
St = 4
GoTo Quit_Prog
End If
Return
'-----
Quit_Prog:
If St = 0 Then Range("B17") = "Not Color Win.BMP file"
If St = 1 Then Range("B17") = "H/V is Not multiple of 16"
If St = 2 Then Range("B17") = "Bad Sub-Sample Factor"
If St = 3 Then Range("B17") = "Bad Sample Point Factor"
If St = 4 Then Range("B17") = "Bad CbCr Adjust Factor"
End Sub
お次にDLLの方は・・・・
文字数制限のため、続編にて