I have code that takes a list of documents (PDFs, image files, Word Docs, etc) and appends each into one single PDF.
It has been pointed out to me that when an image that is larger than the page is appended, the aspect ratio is not preserved and the image looks undesirable.
I have looked for more examples without much luck.
I have extracted the code out into a simple Widows Forms application that is attached.
Can you advise me how I can accomplish this? I tried zipping my project, but the 29 MB file could not be attached. I have attached a sample image and here is the code:
string docName = @“14-8158_DSC_850120140721092109.jpg”;
Aspose.Pdf.Document masterDoc = new Aspose.Pdf.Document();
Document pdfDoc = new Aspose.Pdf.Document();
Page page = pdfDoc.Pages.Add();
FileStream imageStream = new FileStream(docName, FileMode.Open);
Bitmap tempimage = new Bitmap(imageStream);
double urx = tempimage.Width;
double ury = tempimage.Height;
//page.Rect.URX = urx;
//page.Rect.URY = ury;
page.Resources.Images.Add(imageStream);
page.Contents.Add(new Operator.GSave());
Aspose.Pdf.Rectangle pagerect = page.Rect;
if (tempimage.Width > pagerect.URX)
urx = pagerect.URX;
if (tempimage.Height > pagerect.URY)
ury = pagerect.URY;
Aspose.Pdf.Rectangle rectangle = new Aspose.Pdf.Rectangle(0, 0, urx, ury);
//Matrix matrix = new Matrix(new double[] { rectangle.URX - rectangle.LLX, 0, 0, rectangle.URY - rectangle.LLY, rectangle.LLX, rectangle.LLY });
Matrix matrix = new Matrix(new double[] { rectangle.URX - rectangle.LLX, 0, 0, rectangle.URY - rectangle.LLY, rectangle.LLX, rectangle.LLY });
page.Contents.Add(new Operator.ConcatenateMatrix(matrix));
XImage ximage = page.Resources.Images[page.Resources.Images.Count];
page.Contents.Add(new Operator.Do(ximage.Name));
page.Contents.Add(new Operator.GRestore());
masterDoc.Pages.Add(pdfDoc.Pages);
imageStream.Close();
imageStream.Dispose();
masterDoc.Save(“TestPdfImage.pdf”);
System.Diagnostics.Process.Start(“TestPdfImage.pdf”);
Hi Joe,
I have tested the scenario and I am able to reproduce the same problem. For the sake of correction, I have logged it in our issue tracking system as PDFNEWNET-38523. We will investigate this issue in detail and will keep you updated on the status of a correction.
We apologize for your inconvenience.
Nayyer, I don’t know that this is necessarily a bug. I think it comes down to how to set the dimensions of Rectangle object so that it is proportionate to the original image dimensions.
Hi Joe,
Thanks for your feedback. We will share our findings as soon as our product team complete the investigation of the issue.
Thanks for your patience and cooperation.
Best Regards,
@jheltibrand
When an image is larger than the PDF page, Aspose.PDF must scale it before placing it. If the width and height are limited independently, the image becomes stretched or squashed, causing its aspect ratio to be lost. To preserve the original proportions, the image must be scaled using a single uniform scale factor based on the page size. After scaling, the image also needs a correct position (top, center, etc.) because the PDF coordinate system starts at the bottom-left corner.
Below are two code snippets with the necessary adjustments: one using the original operator-based approach and one using ImageStamp.
- Original code snippet, updated for the current version of the library and adjusted to preserve the image aspect ratio:
var input = @"c:/pdftest/14-8158_DSC_850120140721092109.jpg";
var output = @"c:/pdftest/14-8158_DSC_850120140721092109_TestPdfImage.pdf";
var masterDoc = new Document();
var pdfDoc = new Document();
Page page = pdfDoc.Pages.Add();
using (FileStream imageStream = new FileStream(input, FileMode.Open, FileAccess.Read))
using (Aspose.Page.Drawing.Bitmap tempImage = new Aspose.Page.Drawing.Bitmap(imageStream))
{
// original image size in pixels
double imgW = tempImage.Width;
double imgH = tempImage.Height;
Rectangle pageRect = page.Rect;
double pageW = pageRect.URX - pageRect.LLX;
double pageH = pageRect.URY - pageRect.LLY;
// scale factor to fit into page, preserving aspect ratio
double scaleX = pageW / imgW;
double scaleY = pageH / imgH;
double scale = Math.Min(Math.Min(scaleX, scaleY), 1.0); // do not scale up if smaller
double targetW = imgW * scale;
double targetH = imgH * scale;
// add image to resources
page.Resources.Images.Add(imageStream);
// graphics state
page.Contents.Add(new GSave());
// place image at top of the page – adjust if you want centering
double llx = 0;
double lly = pageH - targetH;
// Optional: center on page
// double llx = (pageW - targetW) / 2;
// double lly = (pageH - targetH) / 2;
double urx = llx + targetW;
double ury = lly + targetH;
var rect = new Rectangle(llx, lly, urx, ury);
// transformation matrix
var matrix = new Aspose.Pdf.Matrix(new double[]
{
rect.URX - rect.LLX, 0,
0, rect.URY - rect.LLY,
rect.LLX, rect.LLY
});
page.Contents.Add(new ConcatenateMatrix(matrix));
XImage ximage = page.Resources.Images[page.Resources.Images.Count];
page.Contents.Add(new Do(ximage.Name));
page.Contents.Add(new GRestore());
}
masterDoc.Pages.Add(pdfDoc.Pages);
masterDoc.Save(output);
- Code snippet using ImageStamp, also updated to properly scale the image while maintaining its aspect ratio:
var input = @"c:/pdftest/14-8158_DSC_850120140721092109.jpg";
var output = @"c:/pdftest/14-8158_DSC_850120140721092109_TestPdfImage.pdf";
var doc = new Document();
Page page = doc.Pages.Add();
using (Aspose.Page.Drawing.Bitmap bmp = new Aspose.Page.Drawing.Bitmap(input))
{
double imgW = bmp.Width;
double imgH = bmp.Height;
double pageW = page.PageInfo.Width;
double pageH = page.PageInfo.Height;
double scaleX = pageW / imgW;
double scaleY = pageH / imgH;
double scale = Math.Min(Math.Min(scaleX, scaleY), 1.0);
double targetW = imgW * scale;
double targetH = imgH * scale;
var stamp = new ImageStamp(input)
{
Width = targetW,
Height = targetH,
// place image at top of the page - adjust if you want centering
XIndent = 0,
YIndent = pageH - targetH
// Optional: center on page
// XIndent = (pageW - targetW) / 2,
// YIndent = (pageH - targetH) / 2
};
page.AddStamp(stamp);
}
doc.Save(output);