Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert high DPI images to lower DPI for printing throws OutOfMemoryException

I have some images that I'am trying to print out. Those images can come in varying format, from different DPI's to different formats (JPEG, PNG, etc.)

Now what I've done for now, is to load the image into my application and try and convert the dpi to say 96. However in this process i get an OutOfMemoryException, and I'm not sure how to continue.

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
like image 923
Daniel Jørgensen Avatar asked Aug 25 '17 10:08

Daniel Jørgensen


People also ask

How to alter the DPI of an image?

To change an image's DPI in Photoshop, go to Image > Image Size. Uncheck Resample Image, because this setting will upscale your image, which will make it lower quality. Now, next to Resolution, type in your preferred resolution, set as Pixels/Inch.

How to check 300 DPI resolution?

Right-click on the image file and click Properties at the bottom of the menu. In the Properties menu, click the Details tab. Scroll down to the Image section of the menu, you'll see two values that give you your image's DPI: Horizontal Resolution and Vertical Resolution.

How do I determine the DPI of an image?

The DPI of a digital image is calculated by dividing the total number of dots wide by the total number of inches wide OR by calculating the total number of dots high by the total number of inches high.


1 Answers

There is no need to do any DPI conversion. Just create a DrawingVisual and draw a BitmapImage into it with an appropriate size:

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")
like image 199
Clemens Avatar answered Oct 20 '22 02:10

Clemens