PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Wed Apr 24, 2024 8:08 am

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Wed Feb 15, 2012 9:19 am 
Offline

Joined: Wed Feb 15, 2012 8:18 am
Posts: 2
Hi,
I'm developing a test report using PDFSharp and VB.Net, everything is working like charm but now I'm facing a problem that I'm unable to resolve. This test I'm developing is the first stage to deploy PDFSharp as a reporting tool in my company so I have to make some basic functionality for a faster report designing in the future.

This is the function I'm having problem with
Code:
    Private Function imagenRedimensionar(ByVal foto As String, ByVal imgImagen As XImage, ByVal intAltoLimite As Integer, ByVal intAnchoLimite As Integer) As String
        Dim strLogoRedimensionado As String = ""
        Dim strExtension As String
        Dim bmImagen As Bitmap
        Dim intAltoRedimensionado, intAnchoRedimensionado, intContador As Integer
        Try
         'Change the path to the picture so I can save and load the resized one from there.
            strExtension = foto.Substring(foto.IndexOf(CType(".", Char)), foto.Length - foto.IndexOf(CType(".", Char)))
            strLogoRedimensionado = foto.Substring(0, foto.IndexOf(CType(".", Char))) + "_redimensionado" + strExtension

         'Load the original image
            bmImagen = New Bitmap(foto)

         'Get the original heith and with of the picture
            intAltoRedimensionado =  imgImagen.PointHeight
            intAnchoRedimensionado =  imgImagen.PointWidth
         'If one of the properties is bigger than the rectangle is going to fit make it smaller
         'in both sides until de biggest one fits.
            While intAltoRedimensionado > intAltoLimite Or intAnchoRedimensionado > intAnchoLimite
                intAltoRedimensionado = CType(intAltoRedimensionado * 0.95, Integer)
                intAnchoRedimensionado = CType(intAnchoRedimensionado * 0.95, Integer)
            End While
            Dim bmImagenRedimensionada As New Bitmap(bmImagen, intAnchoRedimensionado, intAltoRedimensionado)
            intContador = 0
         'If the file exist it must be in the header of gooter and won't let me save it
            While System.IO.File.Exists(strLogoRedimensionado)
            'So I change the name again (Stupid, change code to use the last resized image if it fits)
                strLogoRedimensionado = foto.Substring(0, foto.IndexOf(CType(".", Char))) + "_redimensionado" + intContador.ToString + strExtension
                intContador += 1
            End While
         'Save the resized picture to the new path
            bmImagenRedimensionada.Save(strLogoRedimensionado)
        Catch ex As Exception
            strLogoRedimensionado = foto
        End Try
      'Return the new path so the resized image can be loaded from there
        Return strLogoRedimensionado
    End Function


The code runs smoothly and without any errors, but when the new picture is created I'm giving the new heith and width in points instead of pixels, thus the picture displayed is always smaller than it should be
Code:
Dim bmImagenRedimensionada As New Bitmap(bmImagen, intAnchoRedimensionado, intAltoRedimensionado)


I would like to know if I can convert the points to pixels or if I can acomplish this in any other way. I also would like not to use MigraDoc since all this code is going to end up in a server and I would only use for this.
Thank you very much,
Iker


Top
 Profile  
Reply with quote  
PostPosted: Wed Feb 15, 2012 2:12 pm 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3096
Location: Cologne, Germany
Hi!

PDF files have no pixels. All co-ordinates are points.

You can draw any image at any size, just specify the desired size in the DrawImage call - no need to modify the image for that.

Absolutely no need for a loop that shrinks images to 95 % until they fit.
Calculate the factor for the X axis, calculate the factor for the Y axis - and then use the minimum of both factors for both axes.

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Thu Feb 16, 2012 7:40 am 
Offline

Joined: Wed Feb 15, 2012 8:18 am
Posts: 2
Hi!
Thanks for your reply, you opened my eyes.
I was so blind into reusing code that I dind't realise a simple rule of three would do the trick.

Thanks a lot,
Iker


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 24, 2013 11:25 am 
Offline

Joined: Tue Oct 01, 2013 12:16 pm
Posts: 8
Location: Brazil, Piracicaba / SP
Hi, sorry to ask a dumb question, but i'm facing the same problem and i'm not getting the idea properly.

Can you elaborate a little more?

I'm asking this because i'm generation an System.Drawing.Bitmap on runtime base on coordinates stored in a SqlServer database. It draws the image perfictly, but i'm not getting the proper way to place it on the PDFPage.

I see that PDF doesn't use Pixels, but the Width and Height of the image is in pixels.

What would be the arguments in the DrawImage that i should use?

_________________
Sammuel S. Miranda
Microsoft Visual Basic .Net and ASP .net Programer
Microsoft Sql Server 2008 Database Designer
Brazil, Piracicaba / SP


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 24, 2013 11:46 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3096
Location: Cologne, Germany
studssw wrote:
I see that PDF doesn't use Pixels, but the Width and Height of the image is in pixels.
If you want to draw the image with 100 DPI, divide width through 100 and you have the width in inches.
XUnit.FromInch(x / 100);

If you want a width of 4 inches, use this:
XUnit.FromInch(4);

If you want a width of 12 centimeters, use this:
XUnit.FromCentimeter(12);

In real life, you probably have a fixed area for the image (e.g. 16 cm x 12 cm). Using the aspect ratio of the image you will then calculate the height for a width of 16 cm and the width for a height of 12 cm - and use the smaller of both pairs.

Using
DrawImage(XImage image, double x, double y, double width, double height)
or
DrawImage(XImage image, XRect rect)
specify the parameters differently, but lead to the same results.

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 24, 2013 12:01 pm 
Offline

Joined: Tue Oct 01, 2013 12:16 pm
Posts: 8
Location: Brazil, Piracicaba / SP
Maybe you guys can give me a help seeing the code i wrote.

_Profile is an instance of a class i wrote that basicaly has only properties for the page (page height, width, margins - all 4) that is collected from an form.

Code:
Private Function GetRect(ByRef Img As PdfSharp.Drawing.XImage) As PdfSharp.Drawing.XRect
        Dim HeightFactor As Double = (Me._Profile.PageHeight - Me._Profile.MarginTop - Me._Profile.MarginBottom) / Img.PointHeight
        Dim WidthFactor As Double = (Me._Profile.PageWidth - Me._Profile.MarginLeft - Me._Profile.MarginRight) / Img.PointWidth
        Dim EndPoint As PdfSharp.Drawing.XPoint = Nothing
        If HeightFactor < WidthFactor Then
            EndPoint = New PdfSharp.Drawing.XPoint((Me._Profile.MarginLeft + (Img.PointWidth * HeightFactor)), (Me._Profile.MarginTop + (Img.PointHeight * HeightFactor)))
        Else
            EndPoint = New PdfSharp.Drawing.XPoint((Me._Profile.MarginLeft + (Img.PointWidth * WidthFactor)), (Me._Profile.MarginTop + (Img.PointHeight * WidthFactor)))
        End If
        Return New PdfSharp.Drawing.XRect(New PdfSharp.Drawing.XPoint(Me._Profile.MarginLeft, Me._Profile.MarginTop), EndPoint)
    End Function

    Friend Function Print(ByRef Room As RoomScripter) As Byte()
        Dim Img As PdfSharp.Drawing.XImage = Room.DrawImage()
        If Img Is Nothing Then
            Return Nothing
        Else
            Dim PdfDocument As New PdfSharp.Pdf.PdfDocument()
            Dim gfx As PdfSharp.Drawing.XGraphics = Me.NewQfx(PdfDocument)
            gfx.DrawImage(Img, Me.GetRect(Img))
            Img.Dispose()
            Dim Stream As New System.IO.MemoryStream()
            PdfDocument.Save(Stream)
            Dim Arr() As Byte = Stream.ToArray()
            Stream.Close()
            Stream.Dispose()
            PdfDocument.Dispose()
            PdfDocument = Nothing
            Return Arr
        End If
    End Function


Even after reading this post and trying to draw an rectangle on the DrawImage method, still, the image gets very smaller then the page. The arguments at the _Profile instance are the measures in millimiters.

_________________
Sammuel S. Miranda
Microsoft Visual Basic .Net and ASP .net Programer
Microsoft Sql Server 2008 Database Designer
Brazil, Piracicaba / SP


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 24, 2013 12:11 pm 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3096
Location: Cologne, Germany
studssw wrote:
The arguments at the _Profile instance are the measures in millimiters.
And where are the calls to XUnit.FromMillimeter()? Convert your millimeters to XUnit and size will be correct.

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Thu Oct 24, 2013 12:50 pm 
Offline

Joined: Tue Oct 01, 2013 12:16 pm
Posts: 8
Location: Brazil, Piracicaba / SP
Thomas, thanks for your answer (and how quick it was :D ).

Yes, i noticed that like minutes afters posting, that's why i'm returning, to place the answer so if anyone else struggles with this, would have the answer as well.

I changed to point instead of to millimiters because the "PointHeight" and "PointWidth" properties of the XImage (and did the code so the image would be placed at the center of the page). The code ended up on something like this:

Code:
Private Function GetRect(ByRef Img As PdfSharp.Drawing.XImage) As PdfSharp.Drawing.XRect
        Dim Height As Double = PdfSharp.Drawing.XUnit.FromMillimeter(Me._Profile.PageHeight - Me._Profile.MarginTop - Me._Profile.MarginBottom).Point
        Dim Width As Double = PdfSharp.Drawing.XUnit.FromMillimeter(Me._Profile.PageWidth - Me._Profile.MarginLeft - Me._Profile.MarginRight).Point
        Dim HeightFactor As Double = Height / Img.PointHeight
        Dim WidthFactor As Double = Width / Img.PointWidth
        Dim EndPoint As PdfSharp.Drawing.XPoint = Nothing
        If HeightFactor < WidthFactor Then
            EndPoint = New PdfSharp.Drawing.XPoint((Img.PointWidth * HeightFactor), (Img.PointHeight * HeightFactor))
        Else
            EndPoint = New PdfSharp.Drawing.XPoint((Img.PointWidth * WidthFactor), (Img.PointHeight * WidthFactor))
        End If
        Dim Res As New PdfSharp.Drawing.XRect(New PdfSharp.Drawing.XPoint(0, 0), EndPoint)
        Height = (Height - Res.Height) / 2
        Width = (Width - Res.Width) / 2
        EndPoint = New PdfSharp.Drawing.XPoint((EndPoint.X + Width), (EndPoint.Y + Height))
        Res = New PdfSharp.Drawing.XRect(New PdfSharp.Drawing.XPoint(Width, Height), EndPoint)
        Return Res
    End Function

    Friend Function Print(ByRef Room As RoomScripter) As Byte()
        Dim Img As PdfSharp.Drawing.XImage = Room.DrawImage()
        If Img Is Nothing Then
            Return Nothing
        Else
            Dim PdfDocument As New PdfSharp.Pdf.PdfDocument()
            Dim gfx As PdfSharp.Drawing.XGraphics = Me.NewQfx(PdfDocument)
            gfx.DrawImage(Img, Me.GetRect(Img))
            Img.Dispose()
            Dim Stream As New System.IO.MemoryStream()
            PdfDocument.Save(Stream)
            Dim Arr() As Byte = Stream.ToArray()
            Stream.Close()
            Stream.Dispose()
            PdfDocument.Dispose()
            PdfDocument = Nothing
            Return Arr
        End If
    End Function


Just to keep explained for anyone else who reads this post in the future, the Print returns an array of Byte so it can be flushed on the ASP.net Response.

Thanks again.
Every time i enter this forum i see lightining speed answers, and thats the best i've seen...

_________________
Sammuel S. Miranda
Microsoft Visual Basic .Net and ASP .net Programer
Microsoft Sql Server 2008 Database Designer
Brazil, Piracicaba / SP


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC


Who is online

Users browsing this forum: Bing [Bot] and 278 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group