mono環境のC#で簡易イメージビューア2「ホイールで拡大縮小」

コンピュータ

マウスホイールで拡大縮小する機能を追加してみました。

// picview2.cs

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.IO;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
/*
ビルド
mcs picview2.cs /r:System.Windows.Forms.dll /r:System.Drawing.dll
実行
mono picview2.exe
*/
class Form1 : Form
{
    // パネル
    Panel panel1 = new Panel()
    {
        Dock = DockStyle.Fill, // クライアント領域全体に敷き詰める
        AllowDrop = true, // ドラグアンドドロップを受け入れる
        AutoScroll = true, // 自動スクロール
        BackColor = Color.Gray,
    };
    // ピクチャボックス
    PictureBox picbox1 = new PictureBox()
    {
        SizeMode = PictureBoxSizeMode.AutoSize, // 画像サイズに合わせてサイズ変更
    };
    // ビットマップ
    Bitmap bitmap1 = null;
    // 拡大率
    double view_scale1 = 1.0d;
    // 表示幅
    int view_width = 0;
    // 表示高さ
    int view_height = 0;
    // 画像オブジェクトの再作成
    void PictureBoxImageRecreate()
    {
        if (picbox1.Image != null) picbox1.Image.Dispose();
        view_width = (int)(bitmap1.Width * view_scale1);
        view_height = (int)(bitmap1.Height * view_scale1);
        picbox1.Image = new Bitmap(view_width, view_height, bitmap1.PixelFormat);
        picbox1.Update();

    }
    // コンストラクタ
    public Form1()
    {
        picbox1.Parent = panel1;
        panel1.Parent = this;
        Size = new Size(800, 600);

        // ドラッグエンター
        panel1.DragEnter += (s, e) =>
        {
            e.Effect = e.Data.GetDataPresent(DataFormats.FileDrop) ? DragDropEffects.Copy : DragDropEffects.None;
        };
        // ドラッグドロップ
        panel1.DragDrop += async (s, e) =>
        {
            string path = ((string[])e.Data.GetData(DataFormats.FileDrop, false))[0];

            // bitmap1を破棄
            if (bitmap1!= null)
            {
                bitmap1.Dispose();
            }
            // bitmap1へ画像ファイルからイメージオブジェクトをセット
            using (FileStream fs = File.OpenRead(path))
            {
                bitmap1 = await Task.Run(() => { return (Bitmap)Image.FromStream(fs); });
            }
            view_scale1 = 1.0d;
            PictureBoxImageRecreate();
        };
        // ペイント
        picbox1.Paint += (s, e) =>
        {
            if (bitmap1 == null) return;

            Graphics g = e.Graphics;
            g.DrawImage(bitmap1, 0, 0, view_width, view_height);
        };
        // ホイール
        this.MouseWheel += (s, e) =>
        {
            if (e.Delta > 0 && view_scale1 <= 10.0d)
            {
                // 拡大率の増加
                view_scale1 = view_scale1 * 1.5d;
                PictureBoxImageRecreate();
            }
            if (e.Delta < 0 && view_scale1 >= 0.1d)
            {
                // 拡大率の減少
                view_scale1 = view_scale1 / 1.5d;
                PictureBoxImageRecreate();
            }
        };
        // マウスダウン
        picbox1.MouseDown += (s, e) =>
        {
            // ホイールボタン
            if (e.Button == MouseButtons.Middle)
            {
                if (view_scale1 != 1.0d)
                {
                    // 拡大率のリセット
                    view_scale1 = 1.0d;
                    PictureBoxImageRecreate();
                }
            }
        };
    }
    // エントリーポイント
    public static void Main()
    {
        Application.Run(new Form1());
    }
}//class

拡縮はアフィン変換(monoで環境ではなぜか動作しませんでした。)ではなく、ペイントイベント時にDrawImageの幅と高さを倍率調整して描画しています。
また、ホイールボタンをクリックで等倍にリセットされます。

コメント