将多个画布控件保存为silverlight / wpf中的图像

时间:2022-08-02 21:21:30

I have a situation where I have a canvas with an image and I lay multiple canvas controls over it and each canvas may have multiple controls drawn on them (Ellipses, Lines, etc). What is the best/most efficient way to save all these canvas controls toone image? I assume WritableBitmap, but how will this work with multiple canvas controls? One given is that each canvas will be the same size.

我有一个情况,我有一个带有图像的画布,我在它上面放置了多个画布控件,每个画布上可能有多个控件(椭圆,直线等)。将所有这些画布控件保存到图像的最佳/最有效方法是什么?我假设WritableBitmap,但是如何使用多个画布控件呢?给出的一个是每个画布大小相同。

EDIT:

This is what I tried. I also tried with the dpi of the original image, which gives me the tiny result.

这就是我试过的。我也尝试了原始图像的dpi,这给了我很小的结果。

BitmapSource bms = (BitmapSource)this.ctlImage.Source;

Matrix m = PresentationSource.FromVisual(this.ctlImgCanvas).CompositionTarget.TransformToDevice; 

RenderTargetBitmap rtb = new RenderTargetBitmap(bms.PixelWidth, bms.PixelHeight, m.M11 * 96.0, m.M22 * 96.0, PixelFormats.Pbgra32);

rtb.Render(this.ctlImgCanvas);

PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(rtb));
            encoder.Save(memStream);

2 个解决方案

#1


0  

This will take care of everything including children of the canvas. You don't need to know the size of the canvas in advance.

这将照顾包括画布的孩子在内的一切。您无需事先知道画布的大小。

Matrix m =
PresentationSource.FromVisual(canvas).CompositionTarget.TransformToDevice;

BitmapSource panelBitmap = new RenderTargetBitmap(
                (int)Math.Floor(canvas.ActualWidth),
                (int)Math.Floor(canvas.ActualHeight),
                m.M11 * 96.0, // For DPI. This hardcoded value is correct. Check WPF DPI
                m.M22 * 96.0, 
                PixelFormats.Default);

panelBitmap.Render(canvas);

using (FileStream fs = File.Open([filename], FileModel.Create, FileAccess.Write))
{
    BitmapEncoder encoder = GetBitmapEncoderForFileExtension([filename]); // See documentation for which encoder to use when.
    encoder.Frames.Add(BitmapFrame.Create(panelBitmap ));
    encoder.Save(fs);
}

#2


0  

Save the container of the Canvas's to a bitmap, it'll pick up all the children.

将Canvas的容器保存到位图,它将拾取所有孩子。

#1


0  

This will take care of everything including children of the canvas. You don't need to know the size of the canvas in advance.

这将照顾包括画布的孩子在内的一切。您无需事先知道画布的大小。

Matrix m =
PresentationSource.FromVisual(canvas).CompositionTarget.TransformToDevice;

BitmapSource panelBitmap = new RenderTargetBitmap(
                (int)Math.Floor(canvas.ActualWidth),
                (int)Math.Floor(canvas.ActualHeight),
                m.M11 * 96.0, // For DPI. This hardcoded value is correct. Check WPF DPI
                m.M22 * 96.0, 
                PixelFormats.Default);

panelBitmap.Render(canvas);

using (FileStream fs = File.Open([filename], FileModel.Create, FileAccess.Write))
{
    BitmapEncoder encoder = GetBitmapEncoderForFileExtension([filename]); // See documentation for which encoder to use when.
    encoder.Frames.Add(BitmapFrame.Create(panelBitmap ));
    encoder.Save(fs);
}

#2


0  

Save the container of the Canvas's to a bitmap, it'll pick up all the children.

将Canvas的容器保存到位图,它将拾取所有孩子。