代码之家  ›  专栏  ›  技术社区  ›  NoWar

RenderTargetBitmap图像质量低问题

  •  2
  • NoWar  · 技术社区  · 8 年前

    我尝试生成 300 dpi 图像使用 RenderTargetBitmap 方法

    尝试使用RenderTargetBitmap时RenderTargetBitmap=新建 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);
    }
    
    1 回复  |  直到 8 年前
        1
  •  4
  •   NoWar    8 年前

    我需要按所需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控件is proxi卡打印到专用打印机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);
    }
    
    推荐文章