5

グラフィックス オブジェクトの内容をビットマップにコピーしようとしています。私はこのコードを使用しています

public static class GraphicsBitmapConverter
{
    [DllImport("gdi32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    private static extern bool BitBlt(IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hdcSrc, int nXSrc, int nYSrc, TernaryRasterOperations dwRop);

    public static Bitmap GraphicsToBitmap(Graphics g, Rectangle bounds)
    {
        Bitmap bmp = new Bitmap(bounds.Width, bounds.Height);

        using (Graphics bmpGrf = Graphics.FromImage(bmp))
        {
            IntPtr hdc1 = g.GetHdc();
            IntPtr hdc2 = bmpGrf.GetHdc();

            BitBlt(hdc2, 0, 0, bmp.Width, bmp.Height, hdc1, 0, 0, TernaryRasterOperations.SRCCOPY);

            g.ReleaseHdc(hdc1);
            bmpGrf.ReleaseHdc(hdc2);
        }

        return bmp;
    }
}

このようにメソッドを使用すると

Graphics g = button1.CreateGraphics();
var bmp = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));

ビットマップにはコンテンツが含まれています。しかし、メソッドを呼び出す前にグラフィックス オブジェクトを描画すると、ビットマップは空白になります。

using (Bitmap bmp = new Bitmap(100, 100))
{
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.FillRectangle(Brushes.Red, 10, 10, 50, 50);
        g.FillRectangle(Brushes.Blue, 20, 20, 50, 50);
        g.FillRectangle(Brushes.Green, 0, 0, bmp.Width, bmp.Height);

        var bmp2 = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));
    }
}

最初のケースでは機能し、後者では機能しないのはなぜですか?

4

3 に答える 3

1

私が理解しているように

    Graphics g = Graphics.FromImage(bmp)

画像に描画するための Graphics コンテキストを作成しますが、

    Graphics g = button1.CreateGraphics();

すでに画面に描画されているコントロール用に作成します。動的に作成されたビットマップを PictureBox に描画してから、ボタンと同じことを行うことができます。

        using (Bitmap bmp = new Bitmap(100, 100)) 
            {
            using (Graphics g = Graphics.FromImage(bmp)) 
                {
                g.FillRectangle(Brushes.Green, 0, 0, bmp.Width, bmp.Height);
                g.FillRectangle(Brushes.Red, 10, 10, 50, 50);
                g.FillRectangle(Brushes.Blue, 20, 20, 50, 50);

                pictureBox1.Image = bmp;
                pictureBox1.Update(); // force an update before doing anything with it
                Graphics g2 = pictureBox1.CreateGraphics();
                var bmp2 = GraphicsBitmapConverter.GraphicsToBitmap(g2, Rectangle.Truncate(g.VisibleClipBounds)); 
                // bmp2 now has the same contents as bmp1
                pictureBox1.Image = null; // bmp is about to be Disposed so remove the reference to it
                }
            }

もちろん、これは既に持っているビットマップを再作成するだけなので、他の用途を念頭に置いていると思います。

于 2011-04-06T16:40:34.437 に答える
0

グラフィックをフラッシュしようとしましたか?

using (Bitmap bmp = new Bitmap(100, 100))
{
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.FillRectangle(Brushes.Red, 10, 10, 50, 50);
        g.FillRectangle(Brushes.Blue, 20, 20, 50, 50);
        g.FillRectangle(Brushes.Green, 0, 0, bmp.Width, bmp.Height);

        g.Flush(); // !!

        var bmp2 = GraphicsBitmapConverter.GraphicsToBitmap(g, Rectangle.Truncate(g.VisibleClipBounds));
    }
}
于 2011-04-20T12:41:41.003 に答える