WPF - 黑色背景周围保存 canvas 为 jpeg
WPF - Black Background surrounding saved canvas as jpeg
我在使用 JpegBitmapEncoder 时遇到困难,因为它正在创建一个放置在黑色矩形中的图像。我没有修复的解决方案。
private void SaveImage(Canvas canvas, string fileName)
{
SaveFileDialog s = new SaveFileDialog();
s.FileName = "Pic";
s.DefaultExt = ".jpg";
s.Filter = "JPG files (.jpg)|*.jpg";
Nullable<bool> result = s.ShowDialog();
if (result == true)
{
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(6646, 3940, 2000d, 2000d, PixelFormats.Pbgra32);
canvas.Measure(new Size((int)canvas.Width, (int)canvas.Height));
canvas.Arrange(new Rect(new Size((int)canvas.Width, (int)canvas.Height)));
renderBitmap.Render(canvas);
string filename = s.FileName;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
using (FileStream file = File.Create(filename))
{
encoder.Save(file);
}
}
}
使用此代码我得到:
但是当我使用 PngBitmap 编码器时,这不会发生。任何人都可以发光吗?
如何删除黑色矩形或通过增加图片尺寸来填充它?
.png
支持透明度,而 .jpg
不支持。我怀疑你的 canvas 的背景是透明的,因为它不知道如何处理它,所以它只保留像素默认值 (0,0,0),即黑色。 png默认为(0,0,0,0),也就是透明的黑色。
或者,您的 canvas 与图像的尺寸不同(您使用硬编码宽度和高度创建图像,而不是使用 canvas 的宽度和高度)。由于它更大,它只渲染 canvas 实际覆盖的部分。
如果是第一种情况,请尝试将 canvas Background="White" 设置为 canvas,这样它就可以不透明地呈现所有背景。如果是第二个,请尝试使用适当的 Fill="White" 创建一个 Rectangle
图像尺寸,并在 canvas 之前先渲染它。像这样:
Rectangle fillBackground = new Rectangle {
Width = 6646,
Height = 3940,
Fill=Brushes.White
}
renderBitmap.Render(fillBackground);
renderBitmap.Render(canvas);
一些建议,您不应该真正使用宽度和高度,对于布局由其父级确定的控件,这些可以是 NAN。您实际上应该使用 Canvas.ActualWidth
和 Canvas.ActualHeight
或 Canvas.RenderSize.Width/Height
。这实际上会一直反映 on-screen 大小。
此外,要根据您的 DPI 选择计算输出图像的大小,您可以使用以下方法:
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(Width * DPI/96,
Height * DPI/96,
DPI, DPI, PixelFormats.Pbgra32);
我在使用 JpegBitmapEncoder 时遇到困难,因为它正在创建一个放置在黑色矩形中的图像。我没有修复的解决方案。
private void SaveImage(Canvas canvas, string fileName)
{
SaveFileDialog s = new SaveFileDialog();
s.FileName = "Pic";
s.DefaultExt = ".jpg";
s.Filter = "JPG files (.jpg)|*.jpg";
Nullable<bool> result = s.ShowDialog();
if (result == true)
{
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(6646, 3940, 2000d, 2000d, PixelFormats.Pbgra32);
canvas.Measure(new Size((int)canvas.Width, (int)canvas.Height));
canvas.Arrange(new Rect(new Size((int)canvas.Width, (int)canvas.Height)));
renderBitmap.Render(canvas);
string filename = s.FileName;
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(renderBitmap));
using (FileStream file = File.Create(filename))
{
encoder.Save(file);
}
}
}
使用此代码我得到:
但是当我使用 PngBitmap 编码器时,这不会发生。任何人都可以发光吗? 如何删除黑色矩形或通过增加图片尺寸来填充它?
.png
支持透明度,而 .jpg
不支持。我怀疑你的 canvas 的背景是透明的,因为它不知道如何处理它,所以它只保留像素默认值 (0,0,0),即黑色。 png默认为(0,0,0,0),也就是透明的黑色。
或者,您的 canvas 与图像的尺寸不同(您使用硬编码宽度和高度创建图像,而不是使用 canvas 的宽度和高度)。由于它更大,它只渲染 canvas 实际覆盖的部分。
如果是第一种情况,请尝试将 canvas Background="White" 设置为 canvas,这样它就可以不透明地呈现所有背景。如果是第二个,请尝试使用适当的 Fill="White" 创建一个 Rectangle
图像尺寸,并在 canvas 之前先渲染它。像这样:
Rectangle fillBackground = new Rectangle {
Width = 6646,
Height = 3940,
Fill=Brushes.White
}
renderBitmap.Render(fillBackground);
renderBitmap.Render(canvas);
一些建议,您不应该真正使用宽度和高度,对于布局由其父级确定的控件,这些可以是 NAN。您实际上应该使用 Canvas.ActualWidth
和 Canvas.ActualHeight
或 Canvas.RenderSize.Width/Height
。这实际上会一直反映 on-screen 大小。
此外,要根据您的 DPI 选择计算输出图像的大小,您可以使用以下方法:
RenderTargetBitmap renderBitmap = new RenderTargetBitmap(Width * DPI/96,
Height * DPI/96,
DPI, DPI, PixelFormats.Pbgra32);