* 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.
ホーム
一覧
検索
最終更新
リンク
ヘルプ
ソース
新規
リンク
手動リンク
自動相互リンク
駄でべWiki:FrontPage
リンク元
検索キー一覧
自動相互リンク表
ヘルプ
整形ルール
プラグインマニュアル
浮子屋商店もよろしく。
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); //元画像を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 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); //保存 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; 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(); //ピクセル毎にマスク処理 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; } } //アンロック srcBmp.UnlockBits(srcData); mskBmp.UnlockBits(mskData); } } } }}
タイムスタンプを変更しない
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); //元画像を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 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); //保存 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; 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(); //ピクセル毎にマスク処理 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; } } //アンロック srcBmp.UnlockBits(srcData); mskBmp.UnlockBits(mskData); } } } }}