代码:
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
的内容大于它的大小...所以白色背景只能覆盖它的一部分,但仍然是丑陋的结果。
(BTW有谁知道为什么需要一些时间来改变背景?我认为它应该立即改变)
我做错了什么吗?如何在剪贴板中获得白色背景透明图像?
更重要的是,我注意到如果将某些PNG图像粘贴到不支持alpha通道的mspaint.exe中,但某些PNG图像的背景会变黑,那么它的背景会保持白色。
是否有类似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
答案 0 :(得分: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(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 { ... }
答案 1 :(得分:0)
我找到了一个更小,更易于阅读的解决方案,我在https://social.msdn.microsoft.com/Forums/vstudio/en-US/a6972b7f-5ccb-422d-b203-134ef9f10084/how-to-capture-entire-usercontrol-image-to-clipboard?forum=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 { ... }