public Bitmap Shadow(Bitmap src, Color color, int width, double opacity = 0.6f, double angle = 315) { Bitmap result = new Bitmap(src); #region Get DPI float dpiX = 96f; float dpiY = 96f; using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { dpiX = g.DpiX; dpiY = g.DpiY; } #endregion int offset = 4 * width; #region Create Effect var effect = new Media.Effects.DropShadowEffect(); effect.BlurRadius = width; effect.Color = color.ToMediaColor(); effect.Direction = angle; effect.Opacity = opacity; effect.ShadowDepth = width; //var effect = new Media.Effects.BlurEffect(); //effect.Radius = 50; #endregion #region Draw source bitmap to DrawingVisual Media.DrawingVisual drawingVisual = new Media.DrawingVisual(); drawingVisual.Effect = effect; using (var drawingContext = drawingVisual.RenderOpen()) { System.Windows.Rect dRect = new System.Windows.Rect(2 * width, 2 * width, src.Width, src.Height); drawingContext.DrawImage(src.ToBitmapSource(), dRect); drawingContext.Close(); } #endregion #region Render the DrawingVisual into a RenderTargetBitmap var rtb = new Media.Imaging.RenderTargetBitmap( src.Width + offset, src.Height + offset, dpiX, dpiY, Media.PixelFormats.Pbgra32); rtb.Render(drawingVisual); #endregion #region Create a System.Drawing.Bitmap var bitmap = new Bitmap(rtb.PixelWidth, rtb.PixelHeight, PixelFormat.Format32bppArgb); #endregion #region Copy the RenderTargetBitmap pixels into the bitmap's pixel buffer var pdata = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); rtb.CopyPixels(System.Windows.Int32Rect.Empty, pdata.Scan0, pdata.Stride * pdata.Height, pdata.Stride); bitmap.UnlockBits(pdata); #endregion #region Crop Transparent Area var rect = bitmap.ContentBound(); result = new Bitmap(rect.Width, rect.Height, bitmap.PixelFormat); using (var g = Graphics.FromImage(result)) { g.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel); } #endregion return(result); }
public Bitmap Shader(Bitmap src, double radius = 10) { Bitmap result = new Bitmap(src); #region Get DPI float dpiX = 96f; float dpiY = 96f; using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { dpiX = g.DpiX; dpiY = g.DpiY; } #endregion int width = (int)Math.Ceiling(radius); int offset = 4 * width; #region Create Effect var effect = new MyShaderEffect(); //Media.Effects.ShaderRenderMode = Media.Effects.ShaderRenderMode.Auto; //effect. #endregion #region Draw source bitmap to DrawingVisual Media.DrawingVisual drawingVisual = new Media.DrawingVisual(); drawingVisual.Effect = effect; using (var drawingContext = drawingVisual.RenderOpen()) { //drawingContext.PushEffect( new Media.Effects.BlurBitmapEffect(), null ); System.Windows.Rect dRect = new System.Windows.Rect(2 * width, 2 * width, src.Width, src.Height); drawingContext.DrawImage(src.ToBitmapSource(), dRect); drawingContext.Close(); } #endregion #region Render the DrawingVisual into a RenderTargetBitmap var rtb = new Media.Imaging.RenderTargetBitmap( src.Width + offset, src.Height * offset, dpiX, dpiY, Media.PixelFormats.Pbgra32); rtb.Render(drawingVisual); #endregion #region Create a System.Drawing.Bitmap var bitmap = new Bitmap(rtb.PixelWidth, rtb.PixelHeight, PixelFormat.Format32bppArgb); #endregion #region Copy the RenderTargetBitmap pixels into the bitmap's pixel buffer var pdata = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, bitmap.PixelFormat); rtb.CopyPixels(System.Windows.Int32Rect.Empty, pdata.Scan0, pdata.Stride * pdata.Height, pdata.Stride); bitmap.UnlockBits(pdata); #endregion #region Crop Opaque var rect = bitmap.ContentBound(); rect.Width = rect.Width < 0 ? 1 : rect.Width + 2; rect.Height = rect.Height < 0 ? 1 : rect.Height + 2; result = new Bitmap(rect.Width, rect.Height, bitmap.PixelFormat); using (var g = Graphics.FromImage(result)) { g.DrawImage(bitmap, 0, 0, rect, GraphicsUnit.Pixel); } #endregion return(result); }
/* * // Windows Forms版 TODO: 直書きあり * public static void DrawString(string str, double fontSize) * { * var window = System.Windows.Application.Current.MainWindow; * * double[] glDoubleColor = new double[4]; * GL.GetDouble(GetPName.CurrentColor, glDoubleColor); * byte glR = (byte)(glDoubleColor[0] * 255); * byte glG = (byte)(glDoubleColor[1] * 255); * byte glB = (byte)(glDoubleColor[2] * 255); * byte glA = (byte)(glDoubleColor[3] * 255); //255; * var glColor = System.Drawing.Color.FromArgb(glA, glR, glG, glB); * System.Drawing.Brush foreground = new System.Drawing.SolidBrush(glColor); * * //var font = new System.Drawing.Font("Arial", 12); * //var font = new System.Drawing.Font(window.FontFamily.Source, (int)window.FontSize); * // 1 point = 1 / 72.0 inch = (1 / 72.0) * 96 = 1.333333 pixel * var font = new System.Drawing.Font(window.FontFamily.Source, (int)(fontSize / 1.333333)); * // サイズ取得用に生成 * var bmp = new System.Drawing.Bitmap(1, 1, System.Drawing.Imaging.PixelFormat.Format32bppArgb); * System.Drawing.SizeF size; * using (var g = System.Drawing.Graphics.FromImage(bmp)) * { * g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; * * size = g.MeasureString(str, font); * } * * // 再生成 * { * int width = (int)size.Width; * //int height = (int)size.Height; * // TODO: テキストのY座標がずれている : 画像の高さが大きすぎる * int height = (int)(size.Height * 0.75); * bmp = new System.Drawing.Bitmap(width, height, * System.Drawing.Imaging.PixelFormat.Format32bppArgb); * } * * using (var g = System.Drawing.Graphics.FromImage(bmp)) * { * g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; * * g.DrawString(str, font, foreground, new System.Drawing.Point(0, 0)); * } * * // check * //bmp.Save("1.bmp"); * * // 上下反転する * bmp.RotateFlip(System.Drawing.RotateFlipType.RotateNoneFlipY); * * var bitmapData = bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), * System.Drawing.Imaging.ImageLockMode.ReadOnly, * System.Drawing.Imaging.PixelFormat.Format32bppArgb); * int bmpWidth = bitmapData.Width; * int bmpHeight = bitmapData.Height; * * bool isTexture = GL.IsEnabled(EnableCap.Texture2D); * bool isBlend = GL.IsEnabled(EnableCap.Blend); * GL.Enable(EnableCap.Texture2D); * GL.Enable(EnableCap.Blend); * GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); * * int texture = GL.GenTexture(); * GL.BindTexture(TextureTarget.Texture2D, texture); * GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, * (int)TextureMinFilter.Linear); * GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, * (int)TextureMagFilter.Linear); * GL.TexImage2D(TextureTarget.Texture2D, 0, * PixelInternalFormat.Rgba, * bmpWidth, bmpHeight, 0, * PixelFormat.Bgra, PixelType.UnsignedByte, bitmapData.Scan0); * * GL.PushMatrix(); * OpenTK.Matrix4d m; * GL.GetDouble(GetPName.ModelviewMatrix, out m); * //GL.Translate(0, 0, -m.M14); * GL.Scale(1.0 / m.M11, 1.0 / m.M22, 1.0 / m.M33); * GL.Scale(FontScale, FontScale, 1.0); // TODO: これを計算で求める必要がある * * GL.Begin(PrimitiveType.Quads); * GL.TexCoord2(0, 0); * GL.Vertex2(0, 0); * * GL.TexCoord2(1, 0); * GL.Vertex2(bmpWidth, 0); * * GL.TexCoord2(1, 1); * GL.Vertex2(bmpWidth, bmpHeight); * * GL.TexCoord2(0, 1); * GL.Vertex2(0, bmpHeight); * GL.End(); * GL.PopMatrix(); * * bmp.UnlockBits(bitmapData); * * if (!isTexture) * { * GL.Disable(EnableCap.Texture2D); * } * if (!isBlend) * { * GL.Disable(EnableCap.Blend); * } * } */ // WPF版 TODO: 直書きあり public static void DrawString(string str, double fontSize) { var window = System.Windows.Application.Current.MainWindow; double[] glDoubleColor = new double[4]; GL.GetDouble(GetPName.CurrentColor, glDoubleColor); var glColor = new System.Windows.Media.Color(); glColor.R = (byte)(glDoubleColor[0] * 255); glColor.G = (byte)(glDoubleColor[1] * 255); glColor.B = (byte)(glDoubleColor[2] * 255); glColor.A = (byte)(glDoubleColor[3] * 255); //255; System.Windows.Media.Brush foreground = new System.Windows.Media.SolidColorBrush(glColor); //System.Windows.Media.Brush foreground = window.Foreground; var text = new System.Windows.Media.FormattedText( str, new System.Globalization.CultureInfo("en-us"), System.Windows.FlowDirection.LeftToRight, new System.Windows.Media.Typeface( window.FontFamily, System.Windows.FontStyles.Normal, System.Windows.FontWeights.Normal, new System.Windows.FontStretch()), fontSize, //window.FontSize, foreground); var drawingVisual = new System.Windows.Media.DrawingVisual(); using (System.Windows.Media.DrawingContext drawingContext = drawingVisual.RenderOpen()) { drawingContext.DrawText(text, new System.Windows.Point(0, 0)); } System.Windows.Media.Imaging.RenderTargetBitmap bmp = null; { int width = (int)text.Width; int height = (int)text.Height; int dpiX = 96; int dpiY = 96; bmp = new System.Windows.Media.Imaging.RenderTargetBitmap( width, height, dpiX, dpiY, System.Windows.Media.PixelFormats.Pbgra32); } bmp.Render(drawingVisual); int bmpWidth = bmp.PixelWidth; int bmpHeight = bmp.PixelHeight; int stride = bmpWidth * 4; byte[] tmpbits = new byte[stride * bmpHeight]; var rectangle = new System.Windows.Int32Rect(0, 0, bmpWidth, bmpHeight); bmp.CopyPixels(rectangle, tmpbits, stride, 0); // 上下反転する byte[] bits = new byte[stride * bmpHeight]; for (int h = 0; h < bmpHeight; h++) { for (int w = 0; w < stride; w++) { bits[h * stride + w] = tmpbits[(bmpHeight - 1 - h) * stride + w]; } } // check //var png = new System.Windows.Media.Imaging.PngBitmapEncoder(); //png.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(bmp)); //using (var fs = new FileStream("1.png", FileMode.Create)) //{ // png.Save(fs); //} bool isTexture = GL.IsEnabled(EnableCap.Texture2D); bool isBlend = GL.IsEnabled(EnableCap.Blend); GL.Enable(EnableCap.Texture2D); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); int texture = GL.GenTexture(); GL.BindTexture(TextureTarget.Texture2D, texture); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, bmpWidth, bmpHeight, 0, PixelFormat.Bgra, PixelType.UnsignedByte, bits); GL.PushMatrix(); OpenTK.Matrix4d m; GL.GetDouble(GetPName.ModelviewMatrix, out m); GL.Scale(1.0 / m.M11, 1.0 / m.M22, 1.0 / m.M33); GL.Scale(FontScale, FontScale, 1.0); // TODO: これを計算で求める必要がある GL.Begin(PrimitiveType.Quads); GL.TexCoord2(0, 0); GL.Vertex2(0, 0); GL.TexCoord2(1, 0); GL.Vertex2(bmpWidth, 0); GL.TexCoord2(1, 1); GL.Vertex2(bmpWidth, bmpHeight); GL.TexCoord2(0, 1); GL.Vertex2(0, bmpHeight); GL.End(); GL.PopMatrix(); if (!isTexture) { GL.Disable(EnableCap.Texture2D); } if (!isBlend) { GL.Disable(EnableCap.Blend); } }