我尝试使用RenderTargetBitmap
方法生成300 dpi图像。
当我尝试使用RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(315, 195, 300, 300, PixelFormats.Pbgra32);
图像变得非常大。
如何解决?
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(315, 195, 96, 96, PixelFormats.Pbgra32);
renderTargetBitmap.Render(gridCard);
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
using (Stream fileStream = File.Create(path))
{
pngImage.Save(fileStream);
}
最佳答案
我需要用所需的DPI(即300)除以默认DPI(即96)来缩放位图的大小。
double w = 315;
double h = 195;
double dpi = 300;
double scale = dpi / 96;
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(
(int)(w * scale), (int)(h * scale), dpi, dpi, PixelFormats.Pbgra32);
更新#1完整解决方案(用于打印WPF控制是专用打印机MAGiCARD Enduro 3E的代理)
private void BtnPrint_Click(object sender, RoutedEventArgs e)
{
try
{
var size = GetElementPixelSize(gridCard);
double w = size.Width;
double h = size.Height;
double dpiScale = 300.0 / 99.9;
double dpiX = 300.0;
double dpiY = 300.0;
RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(Convert.ToInt32((w) * dpiScale), Convert.ToInt32((h) * dpiScale), dpiX, dpiY, PixelFormats.Pbgra32);
renderTargetBitmap.Render(gridCard);
PngBitmapEncoder pngImage = new PngBitmapEncoder();
pngImage.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
var biRotated = new BitmapImage();
using (Stream fileStream = new MemoryStream())
{
pngImage.Save(fileStream);
fileStream.Seek(0, SeekOrigin.Begin);
biRotated.BeginInit();
biRotated.CacheOption = BitmapCacheOption.OnLoad;
biRotated.StreamSource = fileStream;
// biRotated.Rotation = Rotation.Rotate90; // if you need it
biRotated.EndInit();
}
var vis = new DrawingVisual();
var dc = vis.RenderOpen();
dc.DrawImage(biRotated, new Rect { Width = biRotated.Width, Height = biRotated.Height });
dc.Close();
var pdialog = new System.Windows.Controls.PrintDialog();
if (pdialog.ShowDialog() == true)
{
pdialog.PrintVisual(vis, "Proxy-card");
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show("Print error " + ex.Message);
}
}
// https://stackoverflow.com/questions/3286175/how-do-i-convert-a-wpf-size-to-physical-pixels
public Size GetElementPixelSize(UIElement element)
{
Matrix transformToDevice;
var source = PresentationSource.FromVisual(element);
if (source != null)
transformToDevice = source.CompositionTarget.TransformToDevice;
else
{
// IntPtr hWnd = source.Handle;
using (var source1 = new HwndSource(new HwndSourceParameters()))
{
transformToDevice = source1.CompositionTarget.TransformToDevice;
}
}
if (element.DesiredSize == new Size())
element.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
return (Size)transformToDevice.Transform((Vector)element.DesiredSize);
}