I have got a WPF application, and I would like to save a Canvas to a file with a correct DPI value. The Canvas size is the real physical size, eg. 20x10 cm, at 300 DPI, so it's 2362x1181.
I draw images and shapes with DrawingVisual, then I create a RenderTargetBitmap. The size of the rtb is the size of the Canvas. The dpiX and dpiY are 96. I got correct image resolution only with 96 DPI. When I set it to 300, the canvas become upscale, and cropped to 2362x1181. So, it's not good. I tried to modify the canvas width and height value by dpi factor, but didn't work either.
After the RenderTargetBitmap, I use BitmapEncoder, BitmapFrame, and BinaryWriter. See code below. Working great, but the image DPI value will be 96. I've read a tons of topics about reading DPI, resaving image, using SetResolution, but I don't want to loose quality, I don't want to read file and resave it, I don't want to change pixel width/height, etc.
I just really want to save a DrawingVisual with a given DPI. I could write EXIF data for "X Resolution" (uint=282) and "Y Resoulution" (uint=283), but that didn't affect the Image DPI settings, so eg. Photoshop will read 96, not 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();
}
}