(2019.09.03追記)本記事の内容を再度、再構成し、下記の記事を作成しました。
【C#】アフィン変換を用いて画像ビューアを作ろう!
C#にはアフィン変換に用いる行列用の Matrixクラス(名前空間:System.Drawing.Drawing2D) というクラスがあり、これを駆使すると、以下のようなプログラムを比較的簡単に作成することができます。 プログラムの実行ファ...
以下は以前、書いた記事
画像ファイルを開いて、マウスホイールの上下で拡大縮小するソフトは、以前にも作り、旧ブログで公開しているのですが、これはGraphicクラスのTransformプロパティにアフィン変換行列を指定することで、Graphicオブジェクトの描画した画像や線は勝手に拡大縮小表示してくれるという、ワールド変換という機能を使っていました。
【C#】マウスホイールで画像の拡大縮小
【C#】マウスホイールで画像の拡大縮小 画像処理ソリューション
しかし、この方法では拡大した画像の上に線を引くと、線も太く表示されるので、少し使いにくい部分がありました。
そこで、今回は描画する元の領域と、描画先の左上、右上、左下の3点の座標を指定し、この3点からなる四角形(平行四辺形も含む)に合わせて画像を表示してくれるメソッド
public void DrawImage(
Image image,
PointF[] destPoints,
RectangleF srcRect,
GraphicsUnit srcUnit
)
を使って画像ファイルのビューアを作成しました。
動作イメージ
主な機能
- ドラッグ&ドロップでファイルを開く
- マウスホイールの上下による画像の拡大縮小表示
- マウスのボタンを押しながら画像の移動
- マウス左ボタンのダブルクリックで画像全体表示
- マウス右ボタンのダブルクリックで画像等倍表示
- 画像を開いたあと、矢印キーの左右ボタン(←、→)で同一フォルダ内の画像ファイル切替
- ウィンドウ左下にマウスポインタ位置の画像上の座標および輝度値の表示
- ウィンドウ右下に画像の幅x高さxビット数を表示
ダウンロード
公開日 | バージョン | ファイル | 備考 |
2020.07.25 | Ver.1.1.0 | ImageViewer_V110.zip | マウスダブルクリックで発生する例外を修正 |
2018.02.12 | Ver.1.0.0 | ImageViewer_V100.zip | 初版 |
使用方法
プログラムを実行するだけなら、ファイルを解凍し、exeフォルダ内の ImageViewer.exe をダブルクリックすることで、実行できます。
ソースコード(Visual Studio 2015 C#版)はsourceフォルダに格納しています。
←画像処理のためのC#テクニックへ戻る
コメント
こんにちは。
ソースを拝見させていただいた上実際に動かしてみましたが、
とても使い勝手が良く、素晴らしい出来栄えに驚きました。
この度こちらを参考にさせていただきながら、
画像が90度ずつ右に回転するボタンを実装したいと思い、
色々と試してみたのですがなかなかうまくいきません。
ソースを活かしつつ、もし画像を回転させる機能を付けるとしたら
何か良い方法がありますでしょうか。
可能であればご教授いただけましたら幸いです。
harukuさん、コメント頂きありがとうございます。
ここでのサンプルでは、アフィン変換を使って表示しているのですが、そのアフィン変換行列を90°回転させるとできると思います。
ただし、単に、90°回転だけを行うと、表示位置がずれると思うので、画像の中心に回転させたい場合は、以下のページを参考にしてみてください。
https://imagingsolution.net/program/csharp/microsoft-affine-transformation/
https://imagingsolution.net/program/csharp/affine_mutual_transformation/
https://imagingsolution.net/program/csharp/drawimage/
https://imagingsolution.net/program/affine_image_transformations/
ポイントは、
回転させたい中心位置を原点へ平行移動
↓
90°回転
↓
元の位置へ平行移動
となります。
現在、OCR翻訳ツールを作成しています。
新たに簡易画像ビューアを追加しようとしたところ、こちらが大変参考になったのでお礼申し上げます。本当にありがとうございました。
1点だけ、恐縮ながら指摘させて頂きます。
ImageViewer_V100で何も画像を読み込んでいない状態でピクチャーボックスをダブルクリックすると、エラーで落ちます。ご確認ください。
ご指摘頂きありがとうございます。
確かに画像を開かない状態だと落ちるのを確認しました。
画像を開いていないとき(画像がnullのとき)のエラーチェックを追加し、ImageViewer_V110を追加しました。
ちょうど、こういったビューアを作りたくて探していたところでして
大変ありがたく参考にさせて頂きたいと思います。
ImageViewer_V100のビューアを動かしたのですが
TIFFファイルを表示させたら
「private void DispPixelInfo(」の420行目
「 bright += image[picY, picX].ToString();」で
以下のようなエラーが発生しますがなぜなのでしょうか?
型 ‘System.DivideByZeroException’ のハンドルされていない例外が ImagingSolution.Imaging.ImageData.dll で発生しました
追加情報:0 で除算しようとしました。
どこで割り算してる?理由がさっぱり。。
一応、ご報告しておきます。
理由や対処方法などわかりましたら教えて頂ければ僥倖です。
以上
しみず様
ご評価頂き、ありがとうございます。
「 bright += image[picY, picX].ToString();」
の部分ですが、内部的には
ImageDataクラス(こちらはソース非公開)
(参考)https://imagingsolution.net/program/csharp/imagedata_class_open/
でチャンネル数(モノクロの時は1、カラーの時は3)で割っている部分があり、その部分でエラーになっているようです。
こちらでもペイントで作成したカラー画像(24bit)のtiffファイルを開いてみましたが、エラーになる事はありませんでした。
もしかすると、開こうとしているファイルは、少し特殊なファイル(10bitモノクロ画像など)という事はないでしょうか?
このプログラムでTiffファイルを開くときに使用しているのは、System.Drawing.Bitmapクラスで開いているのですが、その部分でエラーになり、最終的に0除算でエラーになっていると思われます。
だからと言って、プログラムがエラーになっていいという訳ではありませんが、エラーの連絡を頂きありがとうございました。