wpf - 将高 DPI 图像转换为低 DPI 进行打印抛出 OutOfMemoryException

标签 wpf vb.net image printing dpi

我有一些我想打印出来的图像。这些图像可以采用不同的格式,从不同的 DPI 到不同的格式(JPEG、PNG 等)

现在我所做的是将图像加载到我的应用程序中并尝试
将 dpi 转换为 96。但是在这个过程中我得到一个 OutOfMemoryException,我不知道如何继续。

Private Sub PrintImage(Optional providedPrintDialog As PrintDialog = Nothing)
    Dim objPrintDialog As PrintDialog
    If providedPrintDialog IsNot Nothing Then
        objPrintDialog = providedPrintDialog
    Else
        objPrintDialog = New PrintDialog()
    End If
    Dim myPanel As New StackPanel
    myPanel.Margin = New Thickness(15)
    Dim myImage As New Controls.Image
    Dim tempBitmapImage = ConvertBitmapToXDPI(Me.SelectedFileViewModel.File.GetPath, 96)
    Dim tempBitmapImageWidth As Integer = CInt(objPrintDialog.PrintableAreaWidth)
    ' A4 max width = 793
    If tempBitmapImage.Width > tempBitmapImageWidth Then
        myImage.Stretch = System.Windows.Media.Stretch.Uniform
    Else
        myImage.Stretch = System.Windows.Media.Stretch.None
    End If
    myImage.Source = tempBitmapImage
    myPanel.Children.Add(myImage)
    myPanel.Measure(New System.Windows.Size(objPrintDialog.PrintableAreaWidth, objPrintDialog.PrintableAreaHeight))
    myPanel.Arrange(New Rect(New System.Windows.Point(0, 0), myPanel.DesiredSize))
    objPrintDialog.PrintVisual(myPanel, "Billede") ' <- OutOfMemoryException thrown here
End Sub

Private Function ConvertBitmapToXDPI(path As String, newDpi As Integer) As BitmapSource
    Using bitmap As Bitmap = DirectCast(System.Drawing.Image.FromFile(path), Bitmap)
        Dim bitmapData = bitmap.LockBits(New System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), System.Drawing.Imaging.ImageLockMode.[ReadOnly], bitmap.PixelFormat)
        Dim bmSource = BitmapSource.Create(
            bitmapData.Width,
            bitmapData.Height, 96, 96, PixelFormats.Bgr24, Nothing,
            bitmapData.Scan0,
            bitmapData.Stride * bitmapData.Height,
            bitmapData.Stride)
            bitmap.UnlockBits(bitmapData)
        Return bmSource
    End Using
End Function

最佳答案

无需进行任何 DPI 转换。只需创建一个 DrawingVisual 并以适当的大小将 BitmapImage 绘制到其中:

Dim image As New BitmapImage()
image.BeginInit()
image.CacheOption = BitmapCacheOption.OnLoad
image.UriSource = New Uri(path)
image.EndInit()
image.Freeze()

Dim size As New Size()

If image.Width < printDialog.PrintableAreaWidth Then
    size.Width = image.Width
    size.Height = image.Height
Else
    size.Width = printDialog.PrintableAreaWidth
    size.Height = size.Width / image.Width * image.Height
End If

Dim visual As New DrawingVisual()

Using dc As DrawingContext = visual.RenderOpen()
    dc.DrawImage(image, New Rect(size))
End Using

printDialog.PrintVisual(visual, "Billede")

关于wpf - 将高 DPI 图像转换为低 DPI 进行打印抛出 OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45879872/

相关文章:

c# - 足以在 WPF Canvas 上调用 Children.Clear 以在添加新控件之前删除旧控件吗?

c# - 如何在圆圈周围放置标签?

mysql - 多个 MySQL 查询

vb.net - 使用VB.net获取计算机的本地IPv4

html - 在 PNG 图像中嵌入 Vimeo 视频

wpf - 如何在 WPF/Surface 中缩放时计算平移

C# WPF IsEnabled 使用多个绑定(bind)?

.net - sqlconnection 未定义

android - 如何在 android 中的 facebook 上发布图像?

asp.net - 在 ASP.Net 中突出显示图像上的区域