代码之家  ›  专栏  ›  技术社区  ›  Andrew Bullock

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

  •  1
  • Andrew Bullock  · 技术社区  · 14 年前

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

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

    我有一个更大的画布(3000+px正方形),剪贴板是空的(在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 回复  |  直到 14 年前
        1
  •  8
  •   Gabe Timothy Khouri    14 年前

    事实证明,为了将图像存储到剪贴板,图像会自动转换为几种格式(BMP、DIB等)的未压缩位图。所以当你有一个10MP的图像,它需要40MB的未压缩(8位RGBA),它可能需要200MB的内存来存储在剪贴板上,以防有人想要其他格式之一。

    你所能做的就是把它放在剪贴板上,而不需要太多的开销。如果使用Reflector,则会看到剪贴板.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
    }
    

    如果您使用一个或两个 true 实例设置为 false ,您可能能够克服一些不必要的复制,并能够将更大的图像放在剪贴板上。