MagickNetで画像を合成してみよう

前回は画像の切り取りかたについて説明しました。

復習

今回は、復習として、いつもの画像を9分割にして保存してみましょう。

リサイズ後の元画像は以下の通り。
sample-mini

サンプルは以下の通りです

        private static void リサイズして9分割()
        {
            var path = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "sample.jpg");
            byte[] byteArray = null;
            var width = 0;
            var height = 0;
            using (var image = new MagickImage(path))
            {
                //リサイズ他にもスケールする%を渡したりなど、いろいろできるので今回は20%指定で
                image.Resize(0.2);

                //リサイズ後のサイズを取得
                width = image.Width;
                height = image.Height;
    
                //pngを指定するよ
                image.Format = MagickFormat.Png;

                //バイト配列に出力
                byteArray = image.ToByteArray();
            }

            foreach (var i in Enumerable.Range(0, 9))
            {

                using (var divImage = new MagickImage(byteArray))
                {
                    var x = width / 3 * (i % 3);
                    var y = height / 3 * (i / 3);
                    //ここで画像を切り取っているよ
                    divImage.Crop(new MagickGeometry(x,y,width / 3,height/3));

                    var outputPngPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), string.Format("image{0}.png", i));
                    divImage.Write(outputPngPath);
                }
            }
        }

今回一度リサイズしpngにした後の結果をファイルに保存するのではなく、

                //バイト配列に出力
                byteArray = image.ToByteArray();

とすることで、そろぞれを9分割して保存するときに、毎回元ネタの画像を読むのではなく既に読み込んであるバイト配列を以下のように後続のMagickImageで利用することができています。

                using (var divImage = new MagickImage(byteArray))
                {

分割後の結果は以下のようになります。

image0 image1 image2
image3 image4 image5
image6 image7 image8

本題

復習はここまでで、今回の本題合成に入ります。

題材として上の分割した画像を合成して、元の画像に戻します。

合成する方法はいくつかありますが今回紹介するのは以下のメソッドを利用した方法です。
オーバーロードが9種類あるのですが、今回は、以下を使います。
MaigckImageInstanceは合成したい画像。
x,yはオフセット、CompositeOperatorは、どうやって合成するのかを指定するEnumとなっています。

    MagickImage.Composite(MaigckImageInstance,x,y,CompositeOperator);

CompositeOperatorに定義されている合成方法には60種類以上があるのですが、今回は特にほかの合成画像と重ねるわけではないのでOverを利用します。

サンプルコードは以下のようになります。
リサイズして9分割した後に、それを復元します。

        private static void リサイズして9分割した後に復元()
        {
            //リサイズして9分割するコードは上記と同じなので省略

            //復元するためのキャンバスを透過色でリサイズ後のサイズで作成します
            using (var canvas = new MagickImage(MagickColor.Transparent, width, height))
            {
                foreach (var i in Enumerable.Range(0, 9))
                {
                    var readPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), string.Format("image{0}.png", i));
                    //ここで分割した画像を読んでいます
                    using (var divImage = new MagickImage(readPath))
                    {
                        var x = width / 3 * (i % 3);
                        var y = height / 3 * (i / 3);
                        //ここで合成しているよ。分割した画像とオフセット、合成方法を渡しています
                        canvas.Composite(divImage, x, y, CompositeOperator.Over);
                    }
                }

                var outputPngPath = System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "image-merge.png");
                canvas.Write(outputPngPath);
            }
        }

すると結果は以下のようになります。
image-merge

このように、合成も簡単にできます。
Overのほかにも60種類上の合成方法(オーバーレイしてみたりなど)がありますのでいろいろなCompositeOperatorを与えてみて確認してみるのも面白いと思います。

Share