c# - 带有 WPF Canvas 的 Clipboard.SetImage 将剪贴板留空以显示大图像

标签 c# .net wpf canvas

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

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

我有一个更大的 Canvas (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 可以

这是怎么回事?

谢谢

最佳答案

事实证明,为了将图像存储到剪贴板,图像会自动转换为多种格式(BMP、DIB 等)的未压缩位图。因此,当您有一个占用 40MB 未压缩(8 位 RGBA)的 10MP 图像时,可能需要 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
}

如果您使用 true 中的一个或两个创建自己的 SetImage 函数版本实例设置为 false ,您也许能够克服一些不必要的复制,并能够将更大的图像放在剪贴板上。

关于c# - 带有 WPF Canvas 的 Clipboard.SetImage 将剪贴板留空以显示大图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3186989/

相关文章:

c# - 如何在 C# 中锁定一个整数?

c# - 在 MVVM (WPF) 中访问 Grid.Children.Add

c# - Intellisense 不适用于 VS2010 中的一个特定项目

c# - Ultra Numeric Editor 仅将默认设置为最多 2 位小数

c# - 将数组从 .Net 应用程序传递到 Oracle 存储过程

.net - LLBLGen "Flattening"表关系

c# - 使用 C# 连接到 OPENVPN

c# - 系统 IO 异常 : the process cannot access the file because it is being used by another process c#

WPF隐藏网格列

wpf - 合并字典中共享的静态资源