前回のつづきです。
大きな画像を表示させるためにピクチャーボックスには縮小された画像を表示する場合があります。そのときもドラッグアンドドロップで選択範囲を指定できるようにします。
拡大率は英語でExpansionrate。そこでこれをプロパティ名にしています。またBitmapというプロパティでは実寸サイズのBitmapなのか拡大縮小されたあとのBitmapなのかわかりにくいので、実寸サイズのBitmapであることがわかるようにFullScaleBitmapという名前に変更します。
変更箇所は以下のとおりです。
FullScaleBitmapのサイズにExpansionrateを掛け合わせたものがピクチャーボックスに描画されるサイズです。またExpansionrateプロパティが変更されたら同じBitmapを表示するときでもピクチャーボックスに描画するものを変更しなければなりません。それからドラッグアンドドロップ(実際にはDragOverやDragDropイベントは使っていない)で範囲の指定をしたときにトリミングされたBitmapを取得する処理を変更しています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
public partial class ScrollPictureBox : UserControl { double _expansionrate = 1.00; public double Expansionrate { set { _expansionrate = value; pictureBox1.Image = GetExpansionBitmap(FullScaleBitmap, value); } get { return _expansionrate; } } // FullScaleBitmapプロパティはあとでさらに変更する Bitmap _fullScaleBitmap = null; public Bitmap FullScaleBitmap { set { _fullScaleBitmap = value; pictureBox1.Image = GetExpansionBitmap(value, Expansionrate); } get { return _fullScaleBitmap; } } // ピクチャーボックスに表示するためのBitmapを取得する Bitmap GetExpansionBitmap(Bitmap bitmap, double expansionrate) { if (bitmap == null) return null; int newWidth = (int)Math.Round(bitmap.Width * expansionrate); int newHeight = (int)Math.Round(bitmap.Height * expansionrate); if (newWidth > 0 && newHeight > 0) { Bitmap newBitmap = new Bitmap(newWidth, newHeight); Graphics g = Graphics.FromImage(newBitmap); g.DrawImage(bitmap, new Rectangle(0, 0, newWidth, newHeight)); g.Dispose(); return newBitmap; } else return null; } protected void OnFinishedDragRectangle() { if (!DoesDrawDragedRectangle) return; if (FullScaleBitmap != null) { // DragedRectangle.GetRectangle()で取得できるのはピクチャーボックス上の座標なので // もし実寸サイズで表示されていた場合の矩形に変換してから処理をする Rectangle rect = DragedRectangle.GetRectangle(); int x = (int)Math.Round(rect.X / Expansionrate); int y = (int)Math.Round(rect.Y / Expansionrate); int width = (int)Math.Round(rect.Width / Expansionrate); int height = (int)Math.Round(rect.Height / Expansionrate); Rectangle rectangle = new Rectangle(x, y, width, height); // 矩形の幅、高さのうち片方が0以下の場合はなにも取得できないのでイベントも発生させない if (rectangle.Width > 0 && rectangle.Height > 0) FinishedDragRectangle?.Invoke(this, new TrimmedBitmapArgs(FullScaleBitmap, rectangle)); } } } |
それからFullScaleBitmapが変更されたときにイベントで知らせてくれるとありがたいですね。FullScaleBitmapプロパティが変更されたらFullScaleBitmapChangedというイベントを発生させます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public partial class ScrollPictureBox : UserControl { public delegate void FullScaleBitmapChangedHandler(object sender, FullScaleBitmapChangedArgs e); public event FullScaleBitmapChangedHandler FullScaleBitmapChanged; Bitmap _fullScaleBitmap = null; public Bitmap FullScaleBitmap { set { _fullScaleBitmap = value; pictureBox1.Image = GetExpansionBitmap(value, Expansionrate); if (value != null) FullScaleBitmapChanged?.Invoke(this, new FullScaleBitmapChangedArgs(value.Width, value.Height)); else FullScaleBitmapChanged?.Invoke(this, new FullScaleBitmapChangedArgs(0, 0)); } get { return _fullScaleBitmap; } } } |
イベントハンドラFullScaleBitmapChangedHandlerの引数で使われているFullScaleBitmapChangedArgsは以下のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class FullScaleBitmapChangedArgs : EventArgs { public FullScaleBitmapChangedArgs(int width, int height) { Width = width; Height = height; } public int Width { get; private set; } = 0; public int Height { get; private set; } = 0; } |