JPG to PDF: The image saved as rotated (Vb .NET)

Ok I am “converting” attched JPG to a PDF, and I am running into some issues

pic.jpeg (1.0 MB)

The following is the code I am using to do the conversion:

            GetImageLicence()
            GetPDFLicence()
            Dim oPDF As Aspose.Pdf.Document = Nothing
            Dim oImage As Aspose.Imaging.Image = Nothing
            Dim nPageHeight As Double
            Dim nPageWidth As Double
            Dim oPDFImage As Aspose.Pdf.Image = Nothing
            Dim oStream As System.IO.MemoryStream = Nothing
            Try
                Try
                    oPDF = New Aspose.Pdf.Document()
                Catch ex As Exception
                    'oResult.Data = ex.Message
                    'oResult.Response = ConverterResponse.unknownerror
                    'Return oResult
                End Try
                'oResult.Action = "Load Image"
                Try
                    oImage = Aspose.Imaging.Image.Load(sFile)
                    'START of fudge
                    Dim oBMPOptions As Aspose.Imaging.ImageOptionsBase = Nothing
                    Try
                        Dim sTempFile As String = System.IO.Path.Combine(AsposeTemp, "tempbmp.bmp")
                        If System.IO.File.Exists(sTempFile) Then
                            System.IO.File.Delete(sTempFile)
                        End If
                        oBMPOptions = New Aspose.Imaging.ImageOptions.BmpOptions
                        oImage.Save(filePath:=sTempFile, options:=oBMPOptions)
                        Try
                            oImage.Dispose()
                        Catch

                        End Try
                        oImage = Nothing
                        oImage = Aspose.Imaging.Image.Load(filePath:=sTempFile)
                    Catch ex As Exception

                    End Try
                    'END of fudge
                Catch ex As Exception
                    'oResult.Data = ex.Message
                    'oResult.Response = ConverterResponse.unknownerror
                    'Return oResult
                End Try
                'oResult.Action = "Add Page for Image"
                Try
                    oPDF.Pages.Add()
                Catch ex As Exception
                    'oResult.Data = ex.Message
                    'oResult.Response = ConverterResponse.unknownerror
                    'Return oResult
                End Try
                'oResult.Action = "Check image height and width and rotate image if necessary"
                Dim dProportion As Double = 1
                Try
                    nPageHeight = oPDF.Pages.Item(1).PageInfo.Height - oPDF.Pages.Item(1).PageInfo.Margin.Top - oPDF.Pages.Item(1).PageInfo.Margin.Bottom
                    nPageWidth = oPDF.Pages.Item(1).PageInfo.Width - oPDF.Pages.Item(1).PageInfo.Margin.Left - oPDF.Pages.Item(1).PageInfo.Margin.Right
                    If CDbl(oImage.Width) > oImage.Height Then
                        If (CDbl(oImage.Width) <= nPageWidth) And (CDbl(oImage.Height) <= nPageHeight) Then
                            'no need to do anything. Image will fit fine "as is"
                        Else
                            oImage.RotateFlip(Aspose.Imaging.RotateFlipType.Rotate90FlipNone)
                        End If
                    End If
                    If nPageHeight < CDbl(oImage.Height) Then
                        dProportion = nPageHeight / CDbl(oImage.Height)
                    End If
                    If nPageWidth < CDbl(oImage.Width) Then
                        If nPageWidth / CDbl(oImage.Width) < dProportion Then
                            dProportion = nPageWidth / CDbl(oImage.Width)
                        End If
                    End If
                Catch ex As Exception
                    'oResult.Data = ex.Message
                    'oResult.Response = ConverterResponse.unknownerror
                    'Return oResult
                End Try

                'oResult.Action = "Save Image to Memory Stream"
                Try
                    oStream = New IO.MemoryStream
                    oImage.Save(oStream)
                    Try
                        oImage.Dispose()
                    Catch

                    End Try
                Catch ex As Exception
                    'oResult.Data = ex.Message
                    'oResult.Response = ConverterResponse.unknownerror
                    'Return oResult
                End Try

                'oResult.Action = "Add Image to PDF "
                Try
                    oPDFImage = New Aspose.Pdf.Image
                    oPDFImage.ImageStream = oStream
                    If dProportion < 1 Then
                        oPDFImage.ImageScale = dProportion
                    End If
                    oPDF.Pages.Item(1).Paragraphs.Add(oPDFImage)
                    oPDF.Save(sToFileName)
                Catch ex As Exception
                    'oResult.Data = ex.Message
                    'oResult.Response = ConverterResponse.unknownerror
                    'Return oResult
                End Try

The problem is that there appears to be some information held internally in the JPG to indicate that the image has been rotated. When I look at the folder containing the image and view the folder content as, for example, “Extra large icons” I see the picture in its correct orientation, as the person took it on their phone. But when I open the image, for example in “Paint Shop Pro”, I see the image rotated 90 degrees to the left.

Look at my code. Between the comments 'START of fudge and 'END of fudge I added some code in which I take the original .jpeg and save it as a .bmp before re-opening it in a new Aspose.Imaging.Image. Once I do that the “rotation” issue is gone and the image loads 90 degrees to the left.

My first question is:
can I do this without this “fudge” ?

Secondly:

The image is larger than A4 size. The PDF page is set to be A4 (portrait) and I try to fit the image into the available space. In order to do this I rotate the image if its width is more than its height, and then I set the imagescale to a proportion that will ensure that it fits. All this is working correctly thanks to the bit of code:
If dProportion < 1 Then
oPDFImage.ImageScale = dProportion
End If

BUT

Originally I did not set the imagescale. And I note that in the resulting PDF the image is made to fit the page. However, the image is resized disproportionally to fit the maximum available width as well as the maximum available height and as a result the image appears “stretched” or “squeezed”. Second question:

Is is possible to get the image resized without affecting its width to height ratio, and without having to programmatically calculate its ImageScale?

My second question is not as urgent as my first, as my code works perfectly fine to suit our needs. But I don’t like having to save the image to a Bitmap and to re-read it from there as per the code within the 'FUDGE comments. I would really hope that there is a better solution to my first question.

for info: sFile is a string containing the path to the original jpeg, and AsposeTemp is a string containing a path to a “temp” folder I create. You can use your own values for those.

@rozeboosje,

I have observed the issues shared by you and have created a working sample project based on provided code. In your code and using the sample JPEG, I am unable to meet the rotation condition on my end. I have also attached the generated PDF for reference as well. Can you please point out the issue in attached sample project?

TestImaging.zip (22.3 KB)
Test.pdf (2.2 MB)

Hello Mudassir

I created my own C:\Imaging Data and C:\Aspose Data folders. For your license you have your own C:\Aspose Data folder. For the Imaging data extract the attached zip.
Imaging Data.zip (1.8 MB)

I added a second .JPG to the test files. pic.jpeg is the original image. By the way… I noticed that when I downloaded pic.jpeg from here (my original post) the “rotation” issue seems to disappear, so I included the original in the Imaging Data zip file. The second image pic2.jpg is a large square image which makes it easier to see the effect of adding an image without setting the ImageScale.

One small thing I noticed was when you translated my sample to C# you added brackets to the calculation for nPageHeight and nPageWidth, but you changed it from a = b - c - d to a = (b - (c - d)) so I corrected that as that should be a = (b - (c + d)) …

Interestingly I observed that with that small error in place the dProportion value was calculated as too large a value which would result in the image being wider than the available space on the PDF page and in that case it ignores the ImageScale and once again stretches the image to fit the entire available space on the page (i.e. within the margins). I also experimented with calculating FixHeight and FixWidth using dProportion but it ignores those values, too and it still scales the image to fit.

With the correction, the output works as desired. See my attached modification of your original solution.
TestImaging.zip (5.4 KB)

So to rephrase my original two questions

  1. Apparently Aspose applies some form of scaling if you insert images into a PDF that are too large to fit in the available space. But it simply scales the Height so it fits, and likewise it scales the Width so it fits, but it doesn’t maintain the image’s aspect ratio. Is there are way to code it so that when it decides to scale an image it will do so while maintaining its aspect ratio?

  2. Is there a more elegant / efficient alternative to my “fudge”?

@rozeboosje,

Thank you for sharing the information with us. I have created an issue with ID IMAGINGNET-3642 in our issue tracking system as investigation to further investigate the issue. We will share the feedback with you as soon as the issue will be addressed.

1 Like

@rozeboosje,

We have investigated the requirements on our end. For matter related to part2 (fudge),
please use the following code to get files TestOK and TestOKSquare (your code is OK except 1 line that turns not to work rest)

try
{

            oPDF = new Aspose.Pdf.Document();
            oImage = Aspose.Imaging.Image.Load(sFile);

            // START of fudge                

            // END of fudge

            oPDF.Pages.Add();

            // oResult.Action = "Check image height and width and rotate image if necessary"
            double dProportion = 1;
            nPageHeight = (oPDF.Pages[1].PageInfo.Height
            - (oPDF.Pages[1].PageInfo.Margin.Top + oPDF.Pages[1].PageInfo.Margin.Bottom));
            nPageWidth = (oPDF.Pages[1].PageInfo.Width
            - (oPDF.Pages[1].PageInfo.Margin.Left + oPDF.Pages[1].PageInfo.Margin.Right));
            if (oImage.Width > oImage.Height)
            {
                if (oImage.Width <= nPageWidth && oImage.Height <= nPageHeight)
                {
                    // no need to do anything. Image will fit fine "as is"
                }
                else
                {
                    oImage.RotateFlip(Aspose.Imaging.RotateFlipType.Rotate90FlipNone);                        
                }

            }

            if (nPageHeight < oImage.Height)
            {
                dProportion = (double)(nPageHeight / oImage.Height);
            }

            if (nPageWidth < oImage.Width)
            {
                if ((double)(nPageWidth / oImage.Width) < dProportion)
                {
                    dProportion = (double)(nPageWidth / oImage.Width);
                }

            }

            oStream = new System.IO.MemoryStream();                
            oImage.Save(oStream, new Aspose.Imaging.ImageOptions.JpegOptions());                

            oPDFImage = new Aspose.Pdf.Image();                                
            oPDFImage.ImageStream = oStream;
            oPDFImage.ImageStream.Seek(0, System.IO.SeekOrigin.Begin);

            if ((dProportion < 1))
            {
                oPDFImage.ImageScale = dProportion;
            }

            oPDF.Pages[1].Paragraphs.Add(oPDFImage);
            oPDF.Save(sToFileName);
        }
        catch (Exception exs)
        {
            String s = exs.StackTrace;
        }
        finally
        {
            if (oPDF != null)
            {
                try { oPDF.Dispose(); }
                catch { }
                oPDF = null;
            }
            if (oPDFImage != null)
            {
                oPDFImage = null;
            }
            if (oImage != null)
            {
                try { oImage.Dispose(); }
                catch { }
                oImage = null;
            }
            if (oStream != null)
            {
                try { oStream.Close(); }
                catch { }
                try { oStream.Dispose(); }
                catch { }
                oStream = null;
            }
        }

        sFile = AsposeTemp + "pic2.jpg";
        sToFileName = AsposeTemp + "TestOKSquare.pdf";
        try
        {
            oPDF = new Aspose.Pdf.Document();
            oImage = Aspose.Imaging.Image.Load(sFile);                

            oPDF.Pages.Add();

            // oResult.Action = "Check image height and width and rotate image if necessary"
            double dProportion = 1;

            /* Original VB code did this:
            nPageHeight =  oPDF.Pages[1].PageInfo.Height -  oPDF.Pages[1].PageInfo.Margin.Top - oPDF.Pages[1].PageInfo.Margin.Bottom;

            So this needs to become a PLUS then if you add brackets                           |
                                                                                              |
                                                                                              V
            nPageHeight = (oPDF.Pages[1].PageInfo.Height - (oPDF.Pages[1].PageInfo.Margin.Top + oPDF.Pages[1].PageInfo.Margin.Bottom));
             */

            nPageHeight = (oPDF.Pages[1].PageInfo.Height
            - (oPDF.Pages[1].PageInfo.Margin.Top + oPDF.Pages[1].PageInfo.Margin.Bottom));
            nPageWidth = (oPDF.Pages[1].PageInfo.Width
            - (oPDF.Pages[1].PageInfo.Margin.Left + oPDF.Pages[1].PageInfo.Margin.Right));
            if (oImage.Width > oImage.Height)
            {
                if (oImage.Width <= nPageWidth && oImage.Height <= nPageHeight)
                {
                    // no need to do anything. Image will fit fine "as is"
                }
                else
                {
                    oImage.RotateFlip(Aspose.Imaging.RotateFlipType.Rotate90FlipNone);
                }

            }

            if (nPageHeight < oImage.Height)
            {
                dProportion = (double)(nPageHeight / oImage.Height);
            }

            if (nPageWidth < oImage.Width)
            {
                if ((double)(nPageWidth / oImage.Width) < dProportion)
                {
                    dProportion = (double)(nPageWidth / oImage.Width);
                }

            }

            oStream = new System.IO.MemoryStream();
            oImage.Save(oStream, new Aspose.Imaging.ImageOptions.JpegOptions());
            oPDFImage = new Aspose.Pdf.Image();
            oPDFImage.ImageStream = oStream;
            if ((dProportion < 1))
            {
                //oPDFImage.FixHeight = (double)oImage.Height * dProportion; 
                //oPDFImage.FixWidth = (double)oImage.Width * dProportion;
                oPDFImage.ImageScale = dProportion;
            }

            oPDF.Pages[1].Paragraphs.Add(oPDFImage);
            oPDF.Save(sToFileName);
        }
        catch (Exception exs)
        {
            String s = exs.StackTrace;
        }
        finally
        {
            if (oPDF != null)
            {
                try { oPDF.Dispose(); }
                catch { }
                oPDF = null;
            }
            if (oPDFImage != null)
            {
                oPDFImage = null;
            }
            if (oImage != null)
            {
                try { oImage.Dispose(); }
                catch { }
                oImage = null;
            }
            if (oStream != null)
            {
                try { oStream.Close(); }
                catch { }
                try { oStream.Dispose(); }
                catch { }
                oStream = null;
            }
        }

Related to part1:
As per customer observation
1) .. this is working correctly thanks to the bit of code:
If dProportion < 1 Then
oPDFImage.ImageScale = dProportion
End If
  1. Originally we did not set the imagescale. And have noted that in the resulting PDF the image is made to fit the page. However, the image is resized dis-proportionally to fit the maximum available width as well as the maximum available height and as a result the image appears “stretched” or “squeezed”.

We therefore, request that if it is possible to get the image resized without affecting its width to height ratio, and without having to programmatically calculate its ImageScale?

Thus, you are getting affected by the fact that by default image scaled disproportionately, when it does not fit but inserted onto Aspose.Pdf page.

We suggest that you may please request Aspose.PDF forum in this regard as this request is reasonable to address to Aspose.Pdf team for further processing.

1 Like

Thank you. Have done this, see: Keep image height/width ratio unchanged when inserting a large image

@rozeboosje,

Thank you for your feedback.

1 Like