c# - 将带有 alpha channel 的图像复制到带有自定义背景颜色的剪贴板?

标签 c# wpf canvas clipboard alpha-transparency

代码:

private void Foo(Canvas canvas)
{
    // The content is a bit larger...
    Size size = new Size(canvas.ActualWidth * 1.1, canvas.ActualHeight * 1.2);

    // Create a render bitmap and push the surface to it
    RenderTargetBitmap renderBitmap =
        new RenderTargetBitmap(
        (int)size.Width,
        (int)size.Height,
        96d,
        96d,
        PixelFormats.Pbgra32
    );
    renderBitmap.Render(canvas);

    // Then copy to clipboard
    Clipboard.SetImage(renderBitmap);
}

我需要什么:

将具有透明背景的 Canvas 渲染到图像,然后将其复制到剪贴板(退出简单?不是真的)

问题:

粘贴时,我得到一个黑色背景的丑陋图像

解决方案 1:

canvas.Background = new SolidColorBrush(Colors.White);

没有。这个厚的不行,canvas的背景在接下来的renderBitmap.Render(canvas);

中不会改变

相反,我必须使用计时器,给 WPF 一些时间来更改背景,然后在该计时器的 tick 事件中呈现它。它有效,但不幸的是,canvas 的内容比它的大小大...所以白色背景只能覆盖它的一部分,结果仍然很丑陋。 (顺便说一句,有人知道为什么更改背景需要一些时间吗?我认为应该立即更改)

我做错了什么吗?如何在剪贴板中获取白色背景的前透明图像?

此外,我注意到如果将其粘贴到不支持 alpha channel 的 mspaint.exe 中,一些 PNG 图片的背景会保持白色,但另一些会变成黑色。

如果您粘贴图像的地方不支持 alpha channel ,是否有类似 alternative color 的东西用作背景?我们可以定制吗?

现在我渲染了另一个带有白色内容的BitmapSource,如果有办法将它与作为背景的renderBitmap结合起来,问题就解决了,但我不知道怎么……

int dWidth = (int)size.Width;
int dHeight = (int)size.Height;
int dStride = dWidth * 4;
byte[] pixels = new byte[dHeight * dStride];
for (int i = 0; i < pixels.Length; i++)
{
    pixels[i] = 0xFF;
}
BitmapSource bg = BitmapSource.Create(
    dWidth,
    dHeight,
    96,
    96,
    PixelFormats.Pbgra32,
    null,
    pixels,
    dStride
);
// Combine bg with renderBitmap

最佳答案

这是我的最后一个解决方案,希望它能帮助其他遇到同样问题的人

// Create a render bitmap and push the surface to it
RenderTargetBitmap renderBitmap =
    new RenderTargetBitmap(
    (int)size.Width,
    (int)size.Height,
    96d,
    96d,
    PixelFormats.Pbgra32
);
renderBitmap.Render(surface);

// Create a white background render bitmap
int dWidth = (int)size.Width;
int dHeight = (int)size.Height;
int dStride = dWidth * 4;
byte[] pixels = new byte[dHeight * dStride];
for (int i = 0; i < pixels.Length; i++)
{
    pixels[i] = 0xFF;
}
BitmapSource bg = BitmapSource.Create(
    dWidth,
    dHeight,
    96,
    96,
    PixelFormats.Pbgra32,
    null,
    pixels,
    dStride
);

// Adding those two render bitmap to the same drawing visual
DrawingVisual dv = new DrawingVisual();
DrawingContext dc = dv.RenderOpen();
dc.DrawImage(bg, new Rect(size));
dc.DrawImage(renderBitmap, new Rect(size));
dc.Close();

// Render the result
RenderTargetBitmap resultBitmap =
    new RenderTargetBitmap(
    (int)size.Width,
    (int)size.Height,
    96d,
    96d,
    PixelFormats.Pbgra32
);
resultBitmap.Render(dv);

// Copy it to clipboard
try
{
    Clipboard.SetImage(resultBitmap);
} catch { ... }

关于c# - 将带有 alpha channel 的图像复制到带有自定义背景颜色的剪贴板?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10785909/

相关文章:

c# - 在 WPF 应用程序中全局设置文化 (en-IN)

c# - WPF:使用 MVVM 时更改数据绑定(bind)

c# - 如何拖放 DataGrid 列标题?

c# - 奇数和零星的 Chrome 错误 : The chunked cookie is incomplete

c# - 如何在不挂起程序的情况下运行无限循环? (C#)

c# - 合并的 ObservableCollection

canvas - 如何使用 HTML5 Canvas 作为 WebGL 纹理

android 在多行文本上绘制描边

javascript - Angularjs - Kineticjs Canvas toDataUrl 无法在 Chrome 上工作 - 同一域上的图像

c# - 如何使用 C# 替换 HTML 标签内部文本内容!