2

I try to generate 300 dpi image using RenderTargetBitmap method.

When I try to use RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(315, 195, 300, 300, PixelFormats.Pbgra32);

Image gets extremly big.

How to fix it?

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);
}
2
  • What does "extremely big" mean? Commented Jan 23, 2018 at 7:22
  • @KevinGosse When I use new RenderTargetBitmap(315, 195, 96, 96, PixelFormats.Pbgra32); the size is small but when I use new RenderTargetBitmap(315, 195, 300, 300, PixelFormats.Pbgra32); it is big. What I need is the size 315 x 195 and resolution 300 dpi. Commented Jan 23, 2018 at 7:43

1 Answer 1

4

I need to scale the bitmap's size by the desired DPI (i.e. 300) divided by the default DPI (i.e. 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);

UPDATE #1 Full solution (to print WPF Control is proxi-card to special printer 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);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.