* U K I Y A H O N P O *
Nel mezzo del cammin di nostra vita mi ritrovai per una selva oscura,
che la diritta via era smarrita.
リロード   新規 下位ページ作成 編集 凍結 差分 添付 コピー 名前変更   ホーム 一覧 検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
浮子屋商店もよろしく。

C#コード断片/共通/画像にマスクをかける(ビットマップデータを直接扱う) の変更点

Top > C#コード断片 > 共通 > 画像にマスクをかける(ビットマップデータを直接扱う)

NScripterで使われるような、左半分が絵本体で右側がマスクな画像を1枚の透過PNGに戻す処理。

関連
-http://d.hatena.ne.jp/yune_kotomi/20071110/1194698984
-http://d.hatena.ne.jp/ukiya/20071111/1194729728

#code(Csharp,nooutline){{
using System;
using System.IO;
using System.Drawing;
using System.Drawing.Imaging;

namespace MaskTest {
    class Program {
        static void Main(string[] args) {
            foreach (string file in Directory.GetFiles(".", "*.bmp")) {
                //元画像読み込み
                Bitmap srcBmp = (Bitmap)Bitmap.FromFile(file);
	class Program {
		static void Main(string[] args) {
			foreach (string file in Directory.GetFiles(".", "*.bmp")) {
				//元画像読み込み
				Bitmap srcBmp = (Bitmap)Bitmap.FromFile(file);

                //元画像を32bppに変換
                Bitmap tmpBmp = new Bitmap(srcBmp.Width, srcBmp.Height, PixelFormat.Format32bppArgb);
                Graphics tmpG = Graphics.FromImage(tmpBmp);
                tmpG.DrawImage(srcBmp, new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height),
                    new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), GraphicsUnit.Pixel);
				//元画像を32bppに変換
				Bitmap tmpBmp = new Bitmap(srcBmp.Width, srcBmp.Height, PixelFormat.Format32bppArgb);
				Graphics tmpG = Graphics.FromImage(tmpBmp);
				tmpG.DrawImage(srcBmp, new Rectangle(0, 0, tmpBmp.Width, tmpBmp.Height),
					new Rectangle(0, 0, srcBmp.Width, srcBmp.Height), GraphicsUnit.Pixel);

                //左側画像作成
                Bitmap dstBmp = new Bitmap(srcBmp.Width / 2, srcBmp.Height, PixelFormat.Format32bppArgb);
                Graphics dstG = Graphics.FromImage(dstBmp);
                dstG.DrawImage(srcBmp, new Rectangle(0, 0, dstBmp.Width, dstBmp.Height),
                    0, 0, srcBmp.Width / 2, srcBmp.Height, GraphicsUnit.Pixel);
				//左側画像作成
				Bitmap dstBmp = new Bitmap(srcBmp.Width / 2, srcBmp.Height, PixelFormat.Format32bppArgb);
				Graphics dstG = Graphics.FromImage(dstBmp);
				dstG.DrawImage(srcBmp, new Rectangle(0, 0, dstBmp.Width, dstBmp.Height),
					0, 0, srcBmp.Width / 2, srcBmp.Height, GraphicsUnit.Pixel);

                //右側画像作成
                Bitmap mskBmp = new Bitmap(srcBmp.Width / 2, srcBmp.Height, PixelFormat.Format32bppArgb);
                Graphics mskG = Graphics.FromImage(mskBmp);
                mskG.DrawImage(srcBmp, new Rectangle(0, 0, dstBmp.Width, dstBmp.Height),
                    srcBmp.Width/2 , 0, srcBmp.Width / 2, srcBmp.Height, GraphicsUnit.Pixel);
				//右側画像作成
				Bitmap mskBmp = new Bitmap(srcBmp.Width / 2, srcBmp.Height, PixelFormat.Format32bppArgb);
				Graphics mskG = Graphics.FromImage(mskBmp);
				mskG.DrawImage(srcBmp, new Rectangle(0, 0, dstBmp.Width, dstBmp.Height),
					srcBmp.Width/2 , 0, srcBmp.Width / 2, srcBmp.Height, GraphicsUnit.Pixel);

                //マスク処理
                Mask(dstBmp, mskBmp,true);
				//マスク処理
				Mask(dstBmp, mskBmp,true);

                //保存
                dstBmp.Save(file.ToLower().Replace(".bmp", ".png"), ImageFormat.Png);
            }
        }
				//保存
				dstBmp.Save(file.ToLower().Replace(".bmp", ".png"), ImageFormat.Png);
			}
		}

        public unsafe static void Mask(Bitmap srcBmp,Bitmap mskBmp,bool isNegate){
            int w = srcBmp.Width;
            int h = srcBmp.Height;
		public unsafe static void Mask(Bitmap srcBmp,Bitmap mskBmp,bool isNegate){
			int w = srcBmp.Width;
			int h = srcBmp.Height;

            if (mskBmp.Width != w || mskBmp.Height != h) {
                throw new ArgumentException("bitmap size unmatch");
            }
            if (srcBmp.PixelFormat != PixelFormat.Format32bppArgb ||
                mskBmp.PixelFormat != PixelFormat.Format32bppArgb) {
                throw new ArgumentException("bitmap must be 32bpp");
            }
			if (mskBmp.Width != w || mskBmp.Height != h) {
				throw new ArgumentException("bitmap size unmatch");
			}
			if (srcBmp.PixelFormat != PixelFormat.Format32bppArgb ||
				mskBmp.PixelFormat != PixelFormat.Format32bppArgb) {
				throw new ArgumentException("bitmap must be 32bpp");
			}

            //ビットマップをロックしてポインタを取得
            BitmapData srcData = srcBmp.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
            BitmapData mskData = mskBmp.LockBits(new Rectangle(0, 0, w, h),
                ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            byte* pSrcBase = (byte*)srcData.Scan0.ToPointer();
            byte* pMskBase = (byte*)mskData.Scan0.ToPointer();
			//ビットマップをロックしてポインタを取得
			BitmapData srcData = srcBmp.LockBits(new Rectangle(0, 0, w, h),
				ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
			BitmapData mskData = mskBmp.LockBits(new Rectangle(0, 0, w, h),
				ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
			byte* pSrcBase = (byte*)srcData.Scan0.ToPointer();
			byte* pMskBase = (byte*)mskData.Scan0.ToPointer();

            //ピクセル毎にマスク処理
            for (int y = 0; y < h; y++) {
                for (int x = 0; x < w; x++) {
                    byte* pSrc = pSrcBase + (y * w + x) * 4;
                    byte* pMsk = pMskBase + (y * w + x) * 4;
			//ピクセル毎にマスク処理
			for (int y = 0; y < h; y++) {
				for (int x = 0; x < w; x++) {
					byte* pSrc = pSrcBase + (y * w + x) * 4;
					byte* pMsk = pMskBase + (y * w + x) * 4;

                    //mask RGB-> src A  罠:Argbといいつつ格納の順番は逆のBGRA
                    int rgbsum = (*(pMsk + 0) + *(pMsk + 1) + *(pMsk + 2))/3;
                    if (isNegate) {
                        rgbsum = 255 - rgbsum;
                    }
                    *(pSrc + 3) = (byte)rgbsum;
                }
            }
					//mask RGB-> src A  罠:Argbといいつつ格納の順番は逆のBGRA
					int rgbsum = (*(pMsk + 0) + *(pMsk + 1) + *(pMsk + 2))/3;
					if (isNegate) {
						rgbsum = 255 - rgbsum;
					}
					*(pSrc + 3) = (byte)rgbsum;
				}
			}

            //アンロック
            srcBmp.UnlockBits(srcData);
            mskBmp.UnlockBits(mskData);
        }
    }
			//アンロック
			srcBmp.UnlockBits(srcData);
			mskBmp.UnlockBits(mskData);
		}
	}
}
}}