带有WPF画布的Clipboard.SetImage为大图像留下剪贴板为空

时间:2010-07-06 14:15:35

标签: c# .net wpf canvas

我正在将WPF画布渲染到图像并将其粘贴到剪贴板上。

如果画布很小(<900px square),一切正常。

我有一个更大的画布(3000 + px square),剪贴板为空(在photoshop / word等中禁用粘贴选项)

var transform = canvas.LayoutTransform;
canvas.LayoutTransform = null;

var size = new Size(canvas.Width, canvas.Height);

canvas.Measure(size);
canvas.Arrange(new Rect(size));

var renderBitmap = new RenderTargetBitmap((int) size.Width, (int) size.Height, 96d, 96d, PixelFormats.Pbgra32);
renderBitmap.Render(canvas);

canvas.LayoutTransform = transform;

Clipboard.SetImage(renderBitmap);

我没有发现是否存在导致其中断的阈值大小。

3140 x 1903不起作用,3140 x 317

怎么回事?

由于

1 个答案:

答案 0 :(得分:8)

事实证明,为了将图像存储到剪贴板,图像会自动转换为多种格式的未压缩位图(BMP,DIB等)。因此,如果你的10MP图像需要40MB未压缩(8位RGBA),那么可能需要200MB的内存存储在剪贴板上 - 以防万一有人可能想要其他格式之一。

您可以做的就是自己把它放在剪贴板上而不需要太多的开销。如果你使用Reflector,你会看到Clipboard.SetImage看起来像这样:

public static void SetImage(Image image)
{
    if (image == null)
    {
        throw new ArgumentNullException("image");
    }
    IDataObject data = new DataObject();
    data.SetData(DataFormats.Bitmap, true, image); // true means autoconvert
    Clipboard.SetDataObject(data, true); // true means copy
}

如果您创建自己的SetImage函数版本,其中一个或两个true实例设置为false,您可以克服一些不必要的复制并且能够放置一个剪贴板上放大图片。