Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        /*
         * // 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);
            }
        }