PixelFormat.Format32bppArgb の画像に8方向からアルファ値の傾斜をかける
SetGradientAlpha32 をつくった。
ここでやった AlphaGradient と同じように、LinerGradientBrush をつかって
マスクをつくり、すでに設定されているアルファ値に対して任意の傾斜を
設定できる。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.Drawing.Imaging; using System.Drawing.Drawing2D; using ImageUtils; namespace LuminanceToAlpha { public partial class Form1 : Form { public Form1() { InitializeComponent(); } public static bool LuminanceToAlpha(Bitmap bmp, bool bStretch, Color baseColor, out Bitmap result32) { result32 = null; if (bmp.PixelFormat != PixelFormat.Format24bppRgb) return false; int w = bmp.Width; int h = bmp.Height; Bitmap bw = bmp.Clone() as Bitmap; ImgUtils.GrayScale(ref bw); if (bStretch) ImgUtils.HistoStretch(ref bw); result32 = new Bitmap(w, h, PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(result32); g.Clear(baseColor); g.Dispose(); BmpProc8 src = new BmpProc8(bw); BmpProc32 dst = new BmpProc32(result32); for (int y = 0; y <h; y++)<br> for (int x = 0; x <w; x++)<br> { dst[x, y, eRGB.a] = (byte)(255 - src[x, y]); } ImgUtils.CallDispose(dst, src, bw); return true; } public static bool SetAlpha32(ref Bitmap bmp, int percent) { if (bmp.PixelFormat != PixelFormat.Format32bppArgb) return false; int w = bmp.Width; int h = bmp.Height; double p = percent / 100d; BmpProc32 dst = new BmpProc32(bmp); for (int y = 0; y <h; y++)<br> for (int x = 0; x <w; x++)<br> { if (dst[x, y, eRGB.a] == 0) continue; dst[x, y, eRGB.a] = ImgUtils.AdjustByte(dst[x, y, eRGB.a] * p); } dst.Dispose(); return true; } public static void DrawImageCenterAt(Graphics g, Bitmap bmp, int x, int y) { int xx = x - bmp.Width / 2; int yy = y - bmp.Height / 2; g.DrawImage(bmp, xx, yy, bmp.Width, bmp.Height); } public static Bitmap GetGradientMask(int width, int height, float[] factor, float[] position, GradientSide gs) { Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb); Color endColor = Color.White; Color startColor = Color.Black; Point start = new Point(-1, 0); Point end = new Point(0, 0); switch (gs) { case GradientSide.Left: end.X = width; break; case GradientSide.Right: start.X = width; break; case GradientSide.Upper: end.Y = height; break; case GradientSide.Lower: start.Y = height; break; case GradientSide.UpperLeft: end.X = width; end.Y = height; break; case GradientSide.UpperRight: start.X = width; end.Y = height; break; case GradientSide.LowerLeft: start.Y = height; end.X = width; break; case GradientSide.LowerRight: start.X = width; start.Y = height; break; } Blend bl = new Blend(); bl.Factors = factor; bl.Positions = position; LinearGradientBrush br = new LinearGradientBrush( start, end, startColor, endColor); br.Blend = bl; //br.GammaCorrection = true; Rectangle rct = new Rectangle(0, 0, width, height); Graphics g = Graphics.FromImage(bmp); g.FillRectangle(br, rct); g.Dispose(); return bmp; } public static bool SetGradientAlpha32(ref Bitmap bmp32, float[] factor, float[] position, GradientSide gs) { if (bmp32.PixelFormat != PixelFormat.Format32bppArgb) return false; int w = bmp32.Width; int h = bmp32.Height; Bitmap mask = GetGradientMask(w, h, factor, position, gs); byte a; BmpProc24 src = new BmpProc24(mask); BmpProc32 dst = new BmpProc32(bmp32); for (int y = 0; y <h; y++)<br> for (int x = 0; x <w; x++)<br> { a = dst[x, y, eRGB.a]; if (a == 0) continue; dst[x, y, eRGB.a] = ImgUtils.AdjustByte(a * src[x, y, eRGB.r] / 255); } ImgUtils.CallDispose(dst, src, mask); return true; } private void button1_Click(object sender, EventArgs e) { Bitmap bmp = new Bitmap(@"c:HomeImgWorkSGASample2.png"); int w = bmp.Width; int h = bmp.Height; Bitmap tmp1, tmp2; LuminanceToAlpha(bmp, true, Color.FromArgb(120, 0, 0), out tmp1); tmp2 = tmp1.Clone() as Bitmap; float[] position = { 0.0f, 0.2f, 0.4f, 0.6f, 0.8f, 1.0f }; float[] factor = { 1.0f, 0.9f, 0.6f, 0.15f, 0.03f, 0.0f }; SetGradientAlpha32(ref tmp2, factor, position, GradientSide.Left); Graphics g = this.CreateGraphics(); for (int i = 0; i <4; i++)<br> { g.DrawImage(tmp2, 20 + 90 * i, 50 + 45 * i, w, h); } g.DrawImage(tmp1, 20 + 90 * 4, 50 + 45 * 4, w, h); g.Dispose(); tmp2.Dispose(); tmp1.Dispose(); bmp.Dispose(); } } }
SGASample2