画像ビューワーの3回目です。今回は、元画像を表示するサブフォーム・クラスを作成します。
| ・ PN1 | ... AutoScroll : True / Dock : Fill / BackColor : 51,51,51 / BorderStyle : Fixed3D |
| ・ PIC1 | ... (なし) |
| ・ TB1 | ... Appearance : Flat / ImageList : IL1 / ShowToolTips : True |
| ・ IL1 | * 右図参照(数字はImageIndex) * アイコン置き場はこちら |
| ・ ToolBarButton | |
| - tbLarger | ... ToolTipText : 拡大 / ImageIndex : 0 |
| - tbSmaller | ... ToolTipText : 縮小 / ImageIndex : 1 |
| - tbRotateL | ... ToolTipText : 左に回転 / ImageIndex : 2 |
| - tbRotateR | ... ToolTipText : 右に回転 / ImageIndex : 3 |
| - tbFlipX | ... ToolTipText : 左右反転 / ImageIndex : 4 |
| - tbFlipY | ... ToolTipText : 上下反転 / ImageIndex : 5 |
| - tbReload | ... ToolTipText : 再読み込み / ImageIndex : 6 |
| 関数 | 種類 | 機能 |
|---|---|---|
| ・ New | コンストラクタ(オーバーロード) | ファイルを取得してインスタンスを初期化 |
| ・ OnLoad | イベント | 元画像を表示するよう関数の呼び出し |
| ・ OnClosing | イベント | 保持していたイメージの破棄 |
| ・ InitializeImage | ユーザー定義 | 元画像を取得してメモリ上に保持 |
| ・ DrawImage | ユーザー定義 | 元画像を指定の描画サイズで描画 |
SubForm.vb (フォームデザイナのコードは省略しています)
' 内部変数
Private m_path As String = "" ' ファイルのフルパス
Private m_image As Image ' イメージオブジェクト(元画像)
Private m_scale As Single ' スケール(表示倍率)
' コンストラクタ(パス名を指定)
Public Sub New(ByVal path As String)
MyBase.New()
InitializeComponent()
m_path = path ' ファイル名を格納
End Sub
' フォームのロードイベント
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
if m_path <> "" Then InitializeImage() ' 元画像の表示
End Sub
' フォームのアンロードイベント
Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
If Not IsNothing(m_image) Then m_image.Dispose() ' イメージの破棄
End Sub
' 画像の初期化
Public Sub InitializeImage()
If IO.File.Exists(m_path) = False Then
' ファイルが見つからない時
MessageBox.Show("ファイル [" & m_path & "] が見つかりませんでした。", _
"エラー", MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
' 初期化処理
m_scale = 1.0F ' スケール(表示倍率)を1.0倍に初期化
m_image = New Bitmap(m_path) ' 元画像の取得
Me.Text = m_path ' タイトルバーにファイル名を表示
DrawImage() ' 描画
End If
End Sub
' ピクチャボックスへの描画
Private Sub DrawImage()
If IsNothing(m_image) Then Exit Sub
Cursor.Current = Cursors.WaitCursor ' カーソルを待機状態にする
' 描画領域、描画用のイメージ、グラフィックオブジェクトを作成
Dim r As New RectangleF(0, 0, m_image.Width * m_scale, m_image.Height * m_scale)
Dim m As New Bitmap(CInt(r.Width), CInt(r.Height))
Dim g As Graphics = Graphics.FromImage(m)
' 補間モードを指定してメモリ上(m)に描画
g.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
g.DrawImage(m_image, r) ' 元画像を指定領域の大きさに合わせて描画
g.Dispose()
' ピクチャボックス(PIC1)の設定
With PIC1
' 既存のイメージを破棄
If Not IsNothing(.Image) Then .Image.Dispose()
' 位置とサイズの設定(SizeMode を AutoSize にした時は不要)
.Left = PN1.AutoScrollPosition.X
.Top = PN1.AutoScrollPosition.Y
.Width = m.Width
.Height = m.Height
' イメージを取り込み
.Image = m
End With
Cursor.Current = Cursors.Default ' カーソルの形状を元に戻す
End Sub
* InterpolationMode列挙体
・ Bicubic ... 双三次補間
・ Bilinear ... 双一次補間
・ Default ... 既定のモード
・ High ... 高品質補間
・ HighQualityBicubic ... 高品質双三次補間
・ HighQualityBilinear ... 高品質双一次補間
・ Invalid ... QualityMode(レンダリングの品質)のInvalidと等価
・ Low ... 低品質補間
・ NearestNeighbor ... 最近傍補間
' 内部変数/定数
Private m_ratio As Single = 0.2 ' 拡大/縮小率
Const nMinSize As Integer = 32 ' イメージ縮小時の最小サイズ
Const nMaxSize As Integer = 16384 ' イメージ拡大時の最大サイズ
' イメージの拡大・縮小
Private Sub ChangeScale(ByVal ratio As Single)
' スケールの算出(現在のスケール×拡大/縮小率)
Dim f As Single = m_scale * ratio
' 最小サイズ以上最大サイズ以下なら描画
If m_image.Width * f >= nMinSize AndAlso m_image.Height * f >= nMinSize AndAlso _
m_image.Width * f <= nMaxSize AndAlso m_image.Height * f <= nMaxSize Then
m_scale = f ' 算出したスケールを格納
DrawImage() ' 描画
End If
End Sub
(画像の加工)
| 【RotateFlipType列挙体】 | |||
| ・RotateNoneFlipX : 回転なし+左右反転 | ・RotateNoneFlipY : 回転なし+上下反転 | ||
| ・RotateNoneFlipXY : 回転なし+左右反転+上下反転 | ・RotateNoneFlipNone : 回転なし+反転なし | ||
| ・Rotate90FlipX : 90度回転+左右反転 | ・Rotate90FlipY : 90度回転+上下反転 | ||
| ・Rotate90FlipXY : 90度回転+左右反転+上下反転 | ・Rotate90FlipNone : 90度回転+反転なし | ||
| ・Rotate180FlipX : 180度回転+左右反転 | ・Rotate180FlipY : 180度回転+上下反転 | ||
| ・Rotate180FlipXY : 180度回転+左右反転+上下反転 | ・Rotate180FlipNone : 180度回転+反転なし | ||
| ・Rotate270FlipX : 270度回転+左右反転 | ・Rotate270FlipY : 270度回転+上下反転 | ||
| ・Rotate270FlipXY : 270度回転+左右反転+上下反転 | ・Rotate270FlipNone : 270度回転+反転なし | ||
| (回転はすべて右回りの度数) | |||
' イメージの回転
Private Sub ChangeState(ByVal state As RotateFlipType)
If Not IsNothing(m_image) Then
m_image.RotateFlip(state) ' イメージを回転・反転
DrawImage() ' 描画
End If
End Sub
' ツールバーボタンのクリックイベント
Private Sub TB1_ButtonClick(ByVal sender As Object, _
ByVal e As ToolBarButtonClickEventArgs) Handles TB1.ButtonClick
If e.Button Is tbLarger Then
ChangeScale(1 + m_ratio) ' 拡大
ElseIf e.Button Is tbSmaller Then
ChangeScale(1 - m_ratio) ' 縮小
ElseIf e.Button Is tbRotateL Then
ChangeState(RotateFlipType.Rotate270FlipNone) ' 左に回転
ElseIf e.Button Is tbRotateR Then
ChangeState(RotateFlipType.Rotate90FlipNone) ' 右に回転
ElseIf e.Button Is tbFlipX Then
ChangeState(RotateFlipType.RotateNoneFlipX) ' 左右反転
ElseIf e.Button Is tbFlipY Then
ChangeState(RotateFlipType.RotateNoneFlipY) ' 上下反転
ElseIf e.Button Is tbReload Then
InitializeImage() ' 元画像の読み込み
End If
End Sub