我有一个WPF应用程序,我想将Canvas保存到具有正确DPI值的文件中。画布大小是实际的物理大小,例如。 20x10厘米,在300 DPI下,所以是2362x1181。
我用DrawingVisual绘制图像和形状,然后创建一个RenderTargetBitmap。 rtb的大小是Canvas的大小。 dpiX和dpiY为96。只有使用96 DPI才能获得正确的图像分辨率。当我将其设置为300时,画布将变为高档,并裁剪为2362x1181。因此,这不是很好。我试图通过dpi系数修改画布的宽度和高度值,但也没有用。
在RenderTargetBitmap之后,我使用BitmapEncoder,BitmapFrame和BinaryWriter。请参见下面的代码。效果很好,但是图像DPI值为96。我已经阅读了很多有关读取DPI,使用SetResolution保存图像的主题,但是我不想降低质量,我不想读取文件并重新保存它,我不想更改像素的宽度/高度等。
我真的只是想保存带有给定DPI的DrawingVisual。我可以为“ X Resolution”(uint = 282)和“ Y Resoulution”(uint = 283)写EXIF数据,但这并没有影响Image DPI设置,例如。 Photoshop将读取96,而不是300。
BitmapEncoder encoder = new JpegBitmapEncoder();
BitmapFrame bFrame = BitmapFrame.Create(rtb, null, meta, icc);
encoder.Frames.Add(bFrame);
using (var stream = new MemoryStream())
{
encoder.Save(stream);
byte[] imageData = stream.ToArray();
using (FileStream fs = new FileStream(path, ...)
{
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(imageData);
bw.Close();
}
}
答案 0 :(得分:0)
以下方法将UIElement保存为具有指定DPI值的JPEG文件:
public static void SaveElement(UIElement element, double dpi, string path)
{
var visual = new DrawingVisual();
var width = element.RenderSize.Width;
var height = element.RenderSize.Height;
using (var context = visual.RenderOpen())
{
context.DrawRectangle(new VisualBrush(element), null,
new Rect(0, 0, width, height));
}
var bitmap = new RenderTargetBitmap(
(int)(width * dpi / 96), (int)(height * dpi / 96),
dpi, dpi, PixelFormats.Default);
bitmap.Render(visual);
var encocer = new JpegBitmapEncoder();
encocer.Frames.Add(BitmapFrame.Create(bitmap));
using (var stream = File.OpenWrite(path))
{
encocer.Save(stream);
}
}
或者,将DPI缩放比例应用于DrawingVisual:
public static void SaveElement(UIElement element, double dpi, string path)
{
var visual = new DrawingVisual();
var width = element.RenderSize.Width;
var height = element.RenderSize.Height;
using (var context = visual.RenderOpen())
{
context.DrawRectangle(new VisualBrush(element), null,
new Rect(0, 0, width / dpi * 96, height / dpi * 96));
}
var bitmap = new RenderTargetBitmap(
(int)width, (int)height, dpi, dpi, PixelFormats.Default);
bitmap.Render(visual);
var encocer = new JpegBitmapEncoder();
encocer.Frames.Add(BitmapFrame.Create(bitmap));
using (var stream = File.OpenWrite(path))
{
encocer.Save(stream);
}
}
答案 1 :(得分:0)
我尝试将DPI缩放应用于DrawingVisual,但产生的图像质量较差。 :(同样,我尝试将画布设置为756x378(96 DPI大小),然后将RenderTargetBitmap设置为2362x1181和300 DPI,但是这也会产生较低的图像质量。因此,看起来无论是缩小还是放大,然后缩小还是缩小都不是最佳解决方案。DrawingVisual必须使用最终的渲染尺寸。
答案 2 :(得分:0)
毕竟,解决方案似乎是Bitmap SetResolution。我测试了它,看起来像不影响JpegBitmapEncoder()之后的图像质量!并且图像分辨率保持不变,保留元数据,只有DPI会改变!
克莱门斯,还是谢谢您的帮助!
set encoding=utf-8