目次→http://1studying.blogspot.jp/2017/07/c-magicknetmokuzi.html#kuw01
「Magick.NET」は「ImageMagick」のC#版です。
100種類以上の画像フォーマットに対応。
RGBだけで無く、CMYK、グレー、2値画像等が扱えます。
色々な事が出来る分メモリを贅沢に使う為、過度な処理速度は期待しない方がよいでしょう。
RGBメインな画像加工の場合は「OpenCvSharp」の使用も検討してみて下さい。
https://github.com/dlemstra/Magick.NET/tree/master/Documentation
に載っています。
バージョン7.0.0.0102以降は「.NETCore」もサポートされていますが、
今のところWindowsのみ対応となっています。
「Magick.NET」は現在、Macからは使用できないようです。
試しにMacで使用してみたのですが、
「DllNotFoundException」のエラーメッセージで蹴られてしまいました。
Macから呼ばれるDLL関数に対応していないようです。
「GitHub」を覗くと、
Macへの将来的な対応をほのめかしているので今後に期待したいです。
https://github.com/dlemstra/Magick.NET/issues
「GitHub」を覗くと、
Macへの将来的な対応をほのめかしているので今後に期待したいです。
https://github.com/dlemstra/Magick.NET/issues
バージョン6迄と7以降で変更点が多いようです。
不透明度の代わりにアルファを使用するようになっており、
構文の記述に違いがあります。
var6→7への「ImageMagick」の変更点は
https://www.imagemagick.org/script/porting.php
に記載されています。
個人的に嬉しいのは、バージョン7以降でグレースケール画像を使用する際、
今までは「赤、緑、青、アルファ」の4チャンネル消費していたのが、
「グレースケール」1チャンネルの使用に変更されたところです。
私は使った事が無いのですが、
「Magick.NET.Web」というDLLも存在します。
画像処理をXML的な記述でスクリプト化できるようです。
https://github.com/dlemstra/Magick.NET/blob/master/Documentation/Magick.NET.Web.md
に記載されています。
では、「Magick.NET」を使用してみます。
準備
「ファイル→新規作成→プロジェクト」
「テンプレート→VisualC#→Windowsクラシックデスクトップ→Windowsフォームアプリケーション」
を作成します。
↓
私はプロジェクトの名前を「testMagick」としました。
次に、
「ソリューション」を右クリックして「プロパティ」を表示させます。
↓
「構成プロパティ→構成」の「プラットフォーム」が「AnyCPU」である事を
確認しておきます。
(x86やx64を明示しておかなくても対応したMagick.NETのDLLが自動判別されます。)
「NuGet」で「.NET Core」バージョンの「Magick.NET.Core-Q8」等を使う場合、
確認の必要はありません。
今回は「NuGet」で「Magick.NET-Q8-AnyCPU」をインストールします。
(「Q8」は8bit階調0〜255、「Q16」は16bit階調0〜65535が扱えます)
↓
「Form1」のデザイナへ
「button1」、「label1」、「pictureBox1」を配置します。
↓
配置したら、「button1」をダブルクリックして、
「button1」のクリックイベントのコードを表示させておきます。
private void button1_Click(object sender, EventArgs e) { }
テスト用の元画像が必要であれば「神奈川工科大学」のサイトから、
カラーの「Lenna.bmp」画像のオリジナルを取得しておきましょう。
http://www.ess.ic.kanagawa-it.ac.jp/app_images_j.html
レナさんは超有名な標準画像ですね。
ここでのオリジナル「横256×縦256pixel、8bit、RGB画像」を使用します。
(本来のオリジナルで「横512×縦480pixel」版が存在しますが、今回は使用しません)
ここでのオリジナル「横256×縦256pixel、8bit、RGB画像」を使用します。
(本来のオリジナルで「横512×縦480pixel」版が存在しますが、今回は使用しません)
ダウンロードで取得した「Lenna.bmp」画像を、
プロジェクトフォルダの「/bin/Debug」フォルダ内へ入れておいて下さい。
「Magick.NET」を使ってみる
とりあえず使ってみます。
「button1」のクリックイベントのコードを以下の形にします。
private void button1_Click(object sender, EventArgs e) { //ピクチャーボックス表示用 System.Drawing.Bitmap myBitmap; //キャンバス画像を作成 100*50pixel var myMagick = new ImageMagick.MagickImage( new ImageMagick.MagickColor("#00ff00"), 100, 50 ); //ピクチャーボックスへ表示する為、Bitmapへ変換 myBitmap = myMagick.ToBitmap(); //リソース解放 myMagick.Dispose(); //pictureBox1へ表示 pictureBox1.Image = myBitmap; }「実行」して「ボタン」をクリック
↓
「100×50Pixel」の緑の画像を生成し、
ピクチャーボックスへ表示させる為にBitmapへ変換して表示を行いました。
同じ内容を、
usingを使って書く事も出来ます。(IDisposeインターフェースを継承している)
private void button1_Click(object sender, EventArgs e) { //ピクチャーボックス表示用 System.Drawing.Bitmap myBitmap; //キャンバス画像を作成 100*50pixel using (var myMagick = new ImageMagick.MagickImage(new ImageMagick.MagickColor("#00ff00"), 100, 50)) { //ピクチャーボックスへ表示する為、Bitmapへ変換 myBitmap = myMagick.ToBitmap(); } //pictureBox1へ表示 pictureBox1.Image = myBitmap; }当然、処理結果は先程と同じとなります。
言わずもがなですが、
リソース解放や例外処理の事を考えるとusingを使った方がコードが楽に書けます。
描画系
「ImageMagick」の「magick(旧convert)」コマンドの「-draw」系オプションにあたるのが
「new ImageMagick.Drawables()」メソッドです。
メソッドチェーンでの記述が可能です。
楕円と線の描画
「button1」クリックイベントのコードを以下の形に書き換えて下さい。
private void button1_Click(object sender, EventArgs e) { System.Drawing.Bitmap myBitmap; //キャンバス画像を作成 150*150pixel using (var myMagick = new ImageMagick.MagickImage(new ImageMagick.MagickColor("#00ff00"), 150, 150)) { var myDraw=new ImageMagick.Drawables(); myDraw.StrokeColor(ImageMagick.MagickColors.Black); myDraw.StrokeWidth(10); myDraw.FillColor(new ImageMagick.MagickColor("yellow")); myDraw.Ellipse(75, 75, 75, 50, 0, 360); //楕円を描く //メソッドチェーンで線を描く myDraw.StrokeColor(ImageMagick.MagickColors.Blue) .StrokeWidth(10) .Line(50, 50, 100, 100); myDraw.Draw(myMagick); //実描画 myBitmap = myMagick.ToBitmap(); //Bitmapへ変換 } pictureBox1.Image = myBitmap; //pictureBox1へ表示 }↓「実行」して「ボタン」をクリック
このように表示されます。
描画手順も「ImageMagick」で使う「magick(旧convert)」コマンドに近いイメージです。
「-stroke」(線色)オプション→「StrokeColor()」メソッド
「-strokewidth」(中心からの線幅)オプション→「StrokeWidth()」メソッド
「-fill」(塗り色)オプション→「FillColor()」メソッド
をそれぞれ使用して「線色、線幅、塗り色」を指定します。
色を何色にするかの指定には以下の記述方法があります。
「new ImageMagick.MagickColor("#00ff00")」
「new ImageMagick.MagickColor(0, ImageMagick.Quantum.Max, 0)」
(「ImageMagick.Quantum.Max」は扱っている階調の最大値が取得できます。
使用しているDLLが「Q8」だと「255」、「Q16」だと「65535」となります。
ここでは、「new ImageMagick.MagickColor(0, 255, 0)」と同じになります。)
「new ImageMagick.MagickColor("green")」
「ImageMagick.MagickColors.Black」
「ImageMagick.MagickColors.None」(塗らない)
使用の「色空間」が「RGB」であればこれらの記述方法で記述を行うと良いでしょう。
角丸四角と文字列の描画
「button1」クリックイベントのコードを以下の形に書き換えて下さい。
private void button1_Click(object sender, EventArgs e) { System.Drawing.Bitmap myBitmap; //キャンバス画像を作成 150*150pixel using (var myMagick = new ImageMagick.MagickImage(new ImageMagick.MagickColor("#00ff00"), 150, 150)) { //角丸四角と文字列を描く new ImageMagick.Drawables() //角丸四角 .StrokeColor(ImageMagick.MagickColors.Black) .StrokeWidth(3) .FillColor(ImageMagick.MagickColors.None) //塗りを行わない .RoundRectangle(10,10,140,140,40,40) //角丸四角描画 //文字列 .FillColor(ImageMagick.MagickColors.Blue) //塗り青 .FontPointSize(60) //文字列の大きさ .Font("Comic Sans") //文字列の書体 .TextAlignment(ImageMagick.TextAlignment.Center) //文字列の揃え .Text(75, 75, "Text") //文字列描画 .Draw(myMagick); //実描画 myBitmap = myMagick.ToBitmap(); //Bitmapへ変換 } pictureBox1.Image = myBitmap; //pictureBox1へ表示 }↓「実行」して「ボタン」をクリック
文字列を描画する際、手前で設定していた「線色と線幅」がまだ生きている為、
文字列に黒縁が付いた表示となります。
画像を開いて保存
既に準備してある「/bin/Debug」フォルダ内の「Lenna.bmp」を使用します。
「bmp画像を開く」→「50%縮小」→「グレースケール化」→「tif形式で保存」
「button1」クリックイベントのコードを以下の形に書き換えて下さい。
private void button1_Click(object sender, EventArgs e) { System.Drawing.Bitmap myBitmap; //画像読み込み using (var myMagick = new ImageMagick.MagickImage("./Lenna.bmp")) { myMagick.Resize(new ImageMagick.MagickGeometry("50%")); //縮小 myMagick.Grayscale(new ImageMagick.PixelIntensityMethod()); //グレー変換 //出力形式をtifで書き出し myMagick.Write("./Lenna.tif"); myBitmap = myMagick.ToBitmap(); //Bitmapへ変換 label1.Text=myMagick.Format.ToString(); //フォーマット表示 } pictureBox1.Image = myBitmap; //pictureBox1へ表示 }↓「実行」して「ボタン」をクリック
「Lenna.bmp」の同階層に加工された「Lenna.tif」ファイルが書き出されます。
確認してみて下さい。
レナさんが50%縮小され、グレー化された物がTiff画像で書き出されているはずです。
開いた画像形式(Bmp)とは違う画像形式(Tif)で保存を行っても、
所持している画像フォーマットの形式はファイルを開いた時のまま変わりません。
この例でも「ラベル」が「Bmp3」と表示され、ビットマップのままとなっています。
(「Bmp3」はBitmapのバージョン3という意味です)
「 myMagick.Format = ImageMagick.MagickFormat.Png; 」
とすれば所持フォーマットは任意に変更できます。
「Magick画像」と他バイナリ形式との相互変換
ここでは、「Magick画像」(「Magick.NET」の画像)と、
「ストリーム」や「バイト配列」等の相互変換の方法を説明します。
「ストリーム」や「byte[]」を「Magick画像」として開く
「ストリーム」や「byte[]」の取り扱いについてはリンク先で説明しました。
「C# バッキングストアとストリームについて」…
http://1studying.blogspot.jp/2017/05/c.html
では実際に「Magcik.NET」で画像を開いてみましょう。
「button1」クリックイベントのコードを以下の形に書き換えて下さい。
private async void button1_Click(object sender, EventArgs e) { var myBitmap = new Bitmap(150, 150); //「Bitmap画像」を作成 using (Graphics g = Graphics.FromImage(myBitmap)) { g.FillRectangle(Brushes.LawnGreen, g.VisibleClipBounds); //塗りつぶし g.DrawLine(new Pen(Color.Black, 5), 20, 20, 130, 130); //線を引く } //「Bitmap画像」→「byte[]」へ変換 byte[] byteArray = (byte[])new ImageConverter().ConvertTo(myBitmap, typeof(byte[])); //「byte[]」を「Magick.NET」で開く using (var myMagick = new ImageMagick.MagickImage(byteArray)) { new ImageMagick.Drawables() .StrokeColor(ImageMagick.MagickColors.Black) .StrokeWidth(5) .Line(20, 75, 130, 75) .Draw(myMagick); //実描画 pictureBox1.Image = myMagick.ToBitmap(); //pictureBox1へ表示 } await Task.Delay(1000); //非同期で1秒待機 //「byte[]」→「ストリーム」を生成 using (var ms = new System.IO.MemoryStream(byteArray)) { //ストリームを「Magick.NET」で開く using (var myMagick = new ImageMagick.MagickImage(ms)) { new ImageMagick.Drawables() .StrokeColor(ImageMagick.MagickColors.Black) .StrokeWidth(5) .Line(20, 130, 130, 20) .Draw(myMagick); //実描画 pictureBox1.Image = myMagick.ToBitmap(); //pictureBox1へ表示 } }↓「実行」して「ボタン」をクリック
と表示されます。
最初の画像が「byte[]」を「Magick.NET」で開いた物で、
次の画像が「ストリーム」を「Magick.NET」で開いた物です。
「 ImageMagick.MagickImage」クラスは、
コンストラクタ時の引数で「ファイル」、「Bitmap」、「ストリーム」、「byte[]」等、
一通り開けるようです。とても便利。
書き出しは以下のようにします。
「ファイル」や「Bitmap」や「ストリーム」や「byte[]」へ書き出す
「Magick画像」を他の形態へ書き出すには以下の方法があります。
using(var myMagick = new ImageMagick.MagickImage(ファイル読み込み)){ //「ファイル」へ書き出し myMagick.Write(@"./test1.tif"); //「Bitmap画像」へ書き出し Bitmap myBitmap = myMagick.ToBitmap(); //「ストリーム」へ書き出し using (var ms = new System.IO.MemoryStream()) { //(Bmp3はBitmapのバージョン3という意味です) myMagick.Write(ms, ImageMagick.MagickFormat.Bmp3); } //「byte[]」へ書き出し(出力形式をBmp3にして書き出し) myMagick.Format = ImageMagick.MagickFormat.Bmp3; byte[] byteArray = myMagick.ToByteArray(); }
その2へ続きます…
「C# Magick.NETを使ってみる。その2」へ続きます…
http://1studying.blogspot.com/2017/05/c-magicknet_31.html
他
「標準画像/サンプルデータ」は「神奈川工科大学」のサイトの物を利用しました。
http://www.ess.ic.kanagawa-it.ac.jp/app_images_j.html
「ImageMagick コマンドリファレンス」
http://image-magick.com/
IM使用例→http://www.imagemagick.org/Usage/draw/
0 件のコメント:
コメントを投稿