All-About調査室 Annex

ふと湧いた疑問や巷を漂うウワサを全部アバウト~に調査・検証
<OCNから漂着 流浪の調査室>

Jpeg保存dllを使う

2018-04-27 00:14:22 | 4:4:4 Jpeg保存dll作成

ビルドして出来上がったJpeg保存dllをVB.netから呼び出して使ってみる。
プログラムの半分位は以前の自力Tiff保存プログラムを流用して、
ついでにdllの処理時間を計測する機能を付け加えてみた。

で、作ったのが以下のコード。

Imports System.Drawing.Imaging
Imports System.Text

Public Class Form1
    ' dll使用宣言
    Private Declare Function SJP444 _
        Lib "E:\My_Data\Documents\Visual C++\SaveJPG\Release\SaveJPG.dll" _
            (ByRef Source_BGR_Array As Byte, _
             ByVal Width As Integer, _
             ByVal Height As Integer, _
             ByVal Save_File_Name As String, _
             ByVal Q_Coefficient As Byte, _
             ByVal OverWrite As Byte) _
        As Short

    Private PicBox As System.Windows.Forms.PictureBox
    Private Sub Form1_Load(sender As Object, e As EventArgs) _
        Handles MyBase.Load

        ' 通常はVSのフォームデザイナでプロパティ指定する
        ' Form1
        Me.Size = New Size(350, 350)
        Me.AutoScroll = True
        ' PictureBox
        PicBox = New System.Windows.Forms.PictureBox()
        With PicBox
            .SizeMode = PictureBoxSizeMode.AutoSize
            .Image = System.Drawing.Image.FromFile("E:\Test\TestPic.bmp")
                           ' 入力ファイル名をフルパス指定
        End With
        If PicBox.Image.PixelFormat <> PixelFormat.Format24bppRgb Then
            Exit Sub ' 24bit Color以外は処理中断
        End If

        Controls.Add(PicBox)

        Dim imgW, imgH As Integer
        Dim PicBmp As Bitmap
        PicBmp = PicBox.Image.Clone

        imgW = PicBmp.Width  '画像幅
        imgH = PicBmp.Height '画像高

        Dim Rect As New Rectangle(0, 0, imgW, imgH)
        Dim BmpData As System.Drawing.Imaging.BitmapData _
            = PicBmp.LockBits _
              (Rect, Drawing.Imaging.ImageLockMode.ReadWrite, _
               PicBmp.PixelFormat)
        If BmpData.Stride < 0 Then
            PicBmp.UnlockBits(BmpData)
            PicBmp.Dispose()
            Exit Sub ' Strideが負なら処理中断 /(-_-;
        End If

        Dim BDArray(BmpData.Stride * BmpData.Height - 1) As Byte
        System.Runtime.InteropServices.Marshal.Copy _
            (BmpData.Scan0, BDArray, 0, BDArray.Length)
        ' 以下BDArray()を使って画像データにアクセスする

        ' ***** Jpeg保存オプションを指定 *****
        Dim SFN As String = "E:\Test\TestPic.jpg" ' 保存ファイル名をフルパス指定
        Dim QC As Byte = 100 ' Q値 : 1~100
        Dim OWF As Byte = 0  ' 0 =ファイル上書き不許可、0以外 = ファイル上書き許可
        Dim Status As Short  ' dll戻り値

        Dim sw As New System.Diagnostics.Stopwatch()
        If MessageBox.Show _
            ("継続しますか?", "処理時間計測", MessageBoxButtons.YesNo) _
            = DialogResult.No Then GoTo Finish

        sw.Start()
        Status = SJP444(BDArray(0), imgW, imgH, SFN, QC, OWF) ' dll実行
        sw.Stop()
        MsgBox(sw.ElapsedMilliseconds)

        Me.Text = Status ' dll戻り値を画像ウィンドウのタイトルバーに表示
Finish:
        Erase BDArray
        PicBmp.UnlockBits(BmpData)
        PicBmp.Dispose()
    End Sub
End Class

出だしのdll使用宣言の部分について
Lib “・・・”の部分は実際のdllファイルの保管場所に応じて改める。
Saveファイル名(文字列)をdllに渡す部分は ByVal ・・・ As String で渡すのが
キモなのだそうな。(受け取る方は char FName[ ] であるにもかかわらず)

dllに渡す画像データの配列は
  PictureBoxのImageに読み込んで表示する
   ↓
  BitmapクラスにImageのCloneを作る
   ↓
  BitmapにLockBitsをかけてByte配列にMarshal.Copyする
   ↓
  Marshal.Copyを受けたByte配列(の先頭アドレス)をByRefで渡す
の手順で処理している。
なんだかクドい。メンドクサイ。けど、しかたない・・・らしい。

Jpeg保存のオプション指定はDim文で変数に初期値化でやっている。
Q値の範囲は1~100で、この範囲を超えて指定すると
dll側で範囲内に丸めて処理する。
(モチロン As Byte なので300などとByte範囲を超えて書き込めば
VB.netに「ダメ」と言われる)
OWF値は0を指定しておくと、
指定した保存ファイル名のファイルが既に存在していた場合には
dllが処理を中止し、上書きされない。
(0以外では上書きする。特に事前の警告は出ない)

青文字部分がdll処理時間の計測・表示のための処理。
(“継続しますか?”のMessageBoxは無くても良い)

Me.Text = Statusでdllからの戻り値を画像ウィンドウのタイトルバーに表示する。

で、完成dllの処理時間の計測を行ってみた。

- つづく -



最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。