复制图像的alpha通道与自定义背景色到剪贴板?(Copy image with alpha cha

2019-06-24 21:08发布

代码:

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);
}

我需要的 :

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

问题:

当贴,我与黑色背景上的丑陋形象

解决方案1:

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

第这种厚不工作,背景canvas会不会在未来发生变化renderBitmap.Render(canvas);

相反,我必须用一个定时器,给WPF一些时间来改变背景,然后使其在计时器的Tick事件。 它的工作原理,但不幸的是,内容canvas是比它的规模更大......所以,白色背景只能覆盖它的一部分,还是丑陋的结果。 (顺便说一句人知道为什么它需要一段时间来改变背景是什么?我认为应该把它立刻改变)

我做错什么了吗? 我怎样才能在剪贴板上白色背景前透明图像?

更重要的是,我注意到一些PNG图像的背景保持白色,如果你将其粘贴到mspaint.exe不支持alpha通道,但一些人变成黑色。

有什么样,说, alternative color ,它是用来作为背景,如果在您贴上您的图像不支持alpha通道的地方吗? 我们可以自定义吗?

现在我渲染另一个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

Answer 1:

这是我最后的解决方案,希望这将帮助其他有同样问题

// 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 { ... }


Answer 2:

我发现一个更小,更好的阅读解决方案,我发现它在https://social.msdn.microsoft.com/Forums/vstudio/en-US/a6972b7f-5ccb-422d-b203-134ef9f10084/how-to -capture-整个-用户控件图像到剪贴板论坛= WPF? :

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

// Render a white background into buffer for clipboard to avoid black background on some elements
Rectangle vRect = new Rectangle()
{
    Width = (int)size.Width,
    Height = (int)size.Height,
    Fill = Brushes.White,
};
vRect.Arrange(new Rect(size));
renderBitmap.Render(vRect);

// renderBitmap is now white, so render your object on it
renderBitmap.Render(surface);

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


文章来源: Copy image with alpha channel to clipboard with custom background color?