画像全体の反転・回転であれば簡単

今回は左右上下反転と回転をやります。といってもBitmapクラスのRotateFlipメソッドを使うだけなので簡単です。

そしてUserControlImageクラス側ではこのような処理をおこないます。

範囲選択されている部分に対する処理

これではちょっと早く終わりすぎなので、範囲選択されている部分のみを左右上下反転したり回転させる方法を考えてみることにします。

まず範囲選択はユーザーコントロールをドラッグ&ドロップすることでおこなうものとします。

今後範囲指定された部分を移動させることも考えています。そのため選択されている矩形とイメージを両方セットで扱えるクラスを作成しました。

イベントハンドラの追加

ユーザーコントロール上にあるピクチャーボックスをドラッグするのでイベントハンドラを追加します。

ドラッグの開始点と終了点から選択範囲を求める

クリックされると範囲選択の開始、マウスボタンが離されると範囲選択の終了です。startPointはマウスがクリックされた座標、endPointはマウスが離された座標です。そして座標はビットマップ上の座標です。

範囲選択が開始された点と終了した点から範囲選択されている矩形を求めることができます。

ビットマップ上でクリックされたのか?

またクリックされる場所はピクチャーボックス内であっても画像がある場所とは限りません。そこでビットマップ上でクリックされたかどうかも調べる必要があります。

OnMouseDownOutOfBitmapメソッドはビットマップが存在しない場所でクリックされたときに呼び出されます。このときの処理はBitmapプロパティで取得されるビットマップを再描画するだけです。

範囲選択の開始点を取得

BitmapRectangleプロパティが nullのときにマウスがクリックされたということは範囲選択の開始点が指定されたということです。そこで自作メソッドのOnMouseDownForSelectRectangleメソッドを呼び出します。

マウスキャプチャして現在選択されているビットマップ上の座標をフィールド変数startPointに保存しています。またマウスボタンが押されていることがわかるようにフィールド変数isMouseDownをtrueにしています。

選択の解除

BitmapRectangleプロパティがnullではないときにマウスがクリックされたということは範囲選択された部分とは別の場所でマウスがクリックされたということです。この場合はOnMouseDownOutOfSelectionメソッドを呼び出して範囲選択を解除します。

startPointとendPointに(-1, -1)をセットしているのは、矩形を求めるかどうかを判断する目印にするためです。

ドラッグ時の処理

次にマウスが移動したときの処理を考えます。範囲選択のメニューが選択されているときにマウスボタンがおされた状態でマウスを動かすと自作メソッドのOnMouseMoveForSelectRectangleがよばれます。

境界線を描画するDrawBoderRectangleメソッド

OnMouseMoveForSelectRectangleメソッドによってDrawBoderRectangleメソッドがよばれます。これは選択されている矩形を求めて境界線が描画されたビットマップを得るメソッドです。戻り値をShowBitmapメソッドに渡すことで境界線が表示されます。

GetRectangleメソッドはフィールド変数startPointとendPointから矩形を求めます。点の座標が(-1,-1)であれば空の矩形を返します。このときは境界線は表示されません。

2点から矩形を求める

GetRectangleメソッドは2点から矩形を求めるメソッドです。

ドラッグが終わったときの処理

マウスボタンが離されたときはどうすればいいのでしょうか? isMouseDownをfalseにします。そして得られた矩形と矩形内のビットマップからBitmapRectangleオブジェクトを生成してプロパティをセットします。

これで範囲選択ができました。

選択範囲ができたら選択部分を反転させる処理をおこないます。

メニューの追加

そのまえにデザイナをつかってメニューを追加します。

メニューが選択されたらUserControlImageクラスのSelectionRotateFlipメソッドを呼び出します。

SelectionRotateFlipメソッド

UserControlImageクラスのSelectionRotateFlipメソッドは以下のとおりです。

BitmapRectangleがnullでないことを確認してからBitmapRectangle.BitmapをBitmap.RotateFlipメソッドで変更します。そして得られたビットマップと元からあるビットマップを合成し、これをBitmapプロパティにセットします。最後にShowBitmapメソッドを呼び出して表示させます。