How to place images dynamically using Aspose.PDF in C#? - c#

I have a C# script where I am using the Aspose.PDF library.
I am trying to place multiple images with a bit of a spacing vertically.
Here is what I am doing.
// Create pdf document
Aspose.Pdf.Document document = new Aspose.Pdf.Document();
Aspose.Pdf.Page page = document.Pages.Add();
Aspose.Pdf.Text.TextFragment text = new Aspose.Pdf.Text.TextFragment("Einstein Picture");
page.Paragraphs.Add(text);
Aspose.Pdf.Rectangle rectangle = new Aspose.Pdf.Rectangle(100, 600, 300, 800);
Aspose.Pdf.Rectangle rectangle1 = new Aspose.Pdf.Rectangle(100, 400, 300, 800);
page.AddImage("C:/Users/Alan/Desktop/image.gif", rectangle);
page.AddImage("C:/Users/Alan/Desktop/s.jpeg", rectangle1);
document.Save("C:/Users/Alan/Desktop/Testpdf.pdf", Aspose.Pdf.SaveFormat.Pdf);
How can I perfectly align pictures vertically with a bit of gap no matter how many pictures there are?
Currently the picture looks like this.

I request you to use below code snippet on your end and then share your kind feedback with us. This will enable you to place multiple images with a bit vertical spacing.
// Instantiate Document object
var pdf = new Aspose.Pdf.Document();
//Add a page to the document
var pdfImageSection = pdf.Pages.Add();
DirectoryInfo dir = new DirectoryInfo(#"D:\Aspose Files\images\");
FileInfo[] files = dir.GetFiles("*.jpg");
//Iterate through multiple images
foreach (var file in files)
{
FileStream stream = new FileStream(file.FullName, FileMode.Open);
System.Drawing.Image img = new System.Drawing.Bitmap(stream);
var image = new Aspose.Pdf.Image { ImageStream = stream };
//Set appearance properties
image.FixHeight = 300;
image.FixWidth = 300;
//Set margins for proper spacing and alignment
image.Margin = new MarginInfo(5, 5, 5, 5);
//Add the image to paragraphs of the document
pdfImageSection.Paragraphs.Add(image);
}
//Save resultant document
pdf.Save(#"D:\Aspose Files\Image2Pdf_out.pdf");
You were simply adding an image on a PDF page whereas this code snippet adds an image to Paragraphs collection and setting the margin property of image object fixes the alignment and spacing of the images.
Please let us know if you need any further assistance. We will be glad to help. For Aspose documentation to manipulate images is here.
I work with Aspose as Developer Evangelist.

Related

Tile an image in PDF using iText7

I would like to be able to fill graphics objects using the tiling pattern functionality that pdf offers. For example, I would like to be able to draw something like this:
iText7 has a few objects related to patterns that could be useful, but I am having trouble figuring out how to use them and it is exceedingly difficult to find examples of similar code online.
iText7 provides the following classes that may be useful:
PdfPattern.Tiling
PatternColor
PdfPatternCanvas
It looks like you should be able to create a PdfPattern.Tiling object which references an image in some way and then create a PatternColor from that tiling object. Then you can set your canvas' fill color to the PatternColor you just created. An example of a function that does this is:
private void SetImageTilingFill(PdfCanvas canvas, PdfImageXObject img)
{
PdfPattern.Tiling tiling = new PdfPattern.Tiling((float)Inches2Points(img.GetHeight() / 96), (float)Inches2Points(img.GetWidth() / 96)); // create tiling object with width and height the size of the img
tiling.GetResources().AddImage(img);// add the image as a resource?
canvas.SetFillColor(new PatternColor(tiling)); // set fill color to PatternColor?
}
So far this approach has not been successful, my rectangle ends up solid black. Any suggestions would be much appreciated.
Using an image as a tile requires setting up the tile (it has a canvas to draw on). And then using it as a fill when drawing.
try (PdfWriter writer = new PdfWriter("tiling.pdf");
PdfDocument document = new PdfDocument(writer)) {
// creating image
ImageData imageData = ImageDataFactory.create("wavy.png");
PdfImageXObject imageXo = new PdfImageXObject(imageData);
// setting up the tile
PdfPattern.Tiling imageTile = new PdfPattern.Tiling(100, 100);
new PdfPatternCanvas(imageTile, document)
.addXObjectFittedIntoRectangle(imageXo, new Rectangle(0, 0, 100, 100))
.release();
PdfPage page = document.addNewPage();
PdfCanvas canvas = new PdfCanvas(page);
//using the tile
canvas.setFillColor(new PatternColor(imageTile));
canvas.rectangle(10, 10, 500, 900).fill();
canvas.release();
}

How to scale text within a fixed rectangle with itext7?

I'm trying to make a pdf document with itext7 in c# which should have fixed rectangles containing varying text that should scale within the boundaries of the (invisible) rectangles.
I have tried to find if there's automatic scaling, but so far only found auto-scaling for formfields. Since the pdf will be used for plotting text, formfields are of no use.
Code below is a snippet placing a 'box' with fixed dimensions, where all the text should be shown scaled (on one line)
float fontSize = 22f;
Text lineTxt = new Text("A VERY LONG TEXT SHOULD BE SCALED").SetFont(lineFont).SetFontSize(fontSize);
iText.Kernel.Geom.Rectangle lineTxtRect = new iText.Kernel.Geom.Rectangle(100, posHeight - 200, (float)plotline.producttype_plotmaxwidthpts, (float)plotline.producttype_plotmaxheightpts);
Div lineDiv = new Div();
lineDiv.SetMaxHeight((float)plotline.producttype_plotmaxheightpts);
lineDiv.SetWidth((float)plotline.producttype_plotmaxwidthpts);
lineDiv.SetHeight((float)plotline.producttype_plotmaxheightpts);
lineDiv.SetVerticalAlignment(VerticalAlignment.MIDDLE);
lineDiv.SetBorder(new DashedBorder(1));
Paragraph linePara = new Paragraph().Add(lineTxt).
SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER).
SetBorder(new DottedBorder(1)).
SetMultipliedLeading(0.7f).
SetMaxHeight((float)plotline.producttype_plotmaxheightpts).
SetHeight((float)plotline.producttype_plotmaxheightpts);
lineDiv.Add(linePara);
new Canvas(PageCanvas, pdf, lineTxtRect).Add(lineDiv).SetBorder(new SolidBorder(1f));
Layout module of iText 7 allows you to simulate rendering of an element (by creating the renderer tree from the element and then using Layout method) and check whether it fits the given area (by checking LayoutResult object). Thus what you can do is check whether the text fits into your fixed rectangle with the given font size. Then you can just do a binary search on the font size.
Here is a sample code:
PdfDocument pdfDocument = new PdfDocument(new PdfWriter(outFileName));
Text lineTxt = new Text("A VERY LONG TEXT SHOULD BE SCALED");
iText.Kernel.Geom.Rectangle lineTxtRect =
new iText.Kernel.Geom.Rectangle(100,200,100,100);
Div lineDiv = new Div();
lineDiv.SetVerticalAlignment(VerticalAlignment.MIDDLE);
lineDiv.SetBorder(new DashedBorder(1));
Paragraph linePara =
new Paragraph()
.Add(lineTxt)
.SetTextAlignment(iText.Layout.Properties.TextAlignment.CENTER)
.SetBorder(new DottedBorder(1))
.SetMultipliedLeading(0.7f);
lineDiv.Add(linePara);
// 1 is the font size that is definitely small enough to draw all the text
float fontSizeL = 1;
// 20 is the maximum value of the font size you want to use
float fontSizeR = 20;
Canvas canvas =
new Canvas(
new PdfCanvas(pdfDocument.AddNewPage()),
pdfDocument,
lineTxtRect);
// Binary search on the font size
while (Math.Abs(fontSizeL - fontSizeR) > 1e-1) {
float curFontSize = (fontSizeL + fontSizeR) / 2;
lineDiv.SetFontSize(curFontSize);
// It is important to set parent for the current element renderer
// to a root renderer.
IRenderer renderer =
lineDiv.CreateRendererSubTree()
.SetParent(canvas.GetRenderer());
LayoutContext context =
new LayoutContext(
new LayoutArea(1, lineTxtRect));
if (renderer.Layout(context).GetStatus() == LayoutResult.FULL) {
// we can fit all the text with curFontSize
fontSizeL = curFontSize;
} else {
fontSizeR = curFontSize;
}
}
// Use the biggest font size that is still small enough to fit all the
// text.
lineDiv.SetFontSize(fontSizeL);
canvas.Add(lineDiv);
pdfDocument.Close();

Create multiline text in PDF document Xamarin Forms Syncfusion

I have struggled a bit with the official Syncfusion Xamarin Forms PDF Documentation. I have managed to create a table, bind it to values and append it to a PdfDocument.
However odd enough, I cannot seem to draw text strings on separate lines. Each text that I try to draw using graphics.DrawString() or TextElement gets drawn on top of each other in the first line of the document.
All the string are AppResources, concatenating each other to form a report from resx files and class objects that represent my data. Many of them need to be rendered as separate phrases and paragraphs.
Is there a working sample on how to append text line after line and in between them to have tables?
Thank you!
Drawing text one after another is possible by using Essential PDF. We can draw text by one after another by using PdfTextElement with PdfLayoutResult or specifying its position in PdfGraphics.DrawString method. Please refer the below code snippet and sample for more details.
//Creates a new PDF document.
PdfDocument doc = new PdfDocument();
//Adds a page.
PdfPage page = doc.Pages.Add();
//create a new PDF string format
PdfStringFormat drawFormat = new PdfStringFormat();
drawFormat.WordWrap = PdfWordWrapType.Word;
drawFormat.Alignment = PdfTextAlignment.Justify;
drawFormat.LineAlignment = PdfVerticalAlignment.Top;
//Set the font.
PdfFont font = new PdfStandardFont(PdfFontFamily.Helvetica, 10f);
//Create a brush.
PdfBrush brush = PdfBrushes.Red;
//bounds
RectangleF bounds = new RectangleF(new PointF(10, 10), new SizeF(page.Graphics.ClientSize.Width - 30, page.Graphics.ClientSize.Height - 20));
//Create a new text elememt
PdfTextElement element = new PdfTextElement(text, font, brush);
//Set the string format
element.StringFormat = drawFormat;
//Draw the text element
PdfLayoutResult result = element.Draw(page, bounds);
// Draw the string one after another.
result = element.Draw(result.Page, new RectangleF(result.Bounds.X, result.Bounds.Bottom + 10, result.Bounds.Width, result.Bounds.Height));
// Creates a PdfLightTable.
PdfLightTable pdfLightTable = new PdfLightTable();
//Add colums to light table
pdfLightTable.Columns.Add(new PdfColumn("Name"));
pdfLightTable.Columns.Add(new PdfColumn("Age"));
pdfLightTable.Columns.Add(new PdfColumn("Sex"));
//Add row
pdfLightTable.Rows.Add(new string[] { "abc", "21", "Male" });
//Includes the style to display the header of the light table.
pdfLightTable.Style.ShowHeader = true;
//Draws PdfLightTable and returns the rendered bounds.
result = pdfLightTable.Draw(page, new PointF(result.Bounds.Left,result.Bounds.Bottom+20));
//draw string with returned bounds from table
result = element.Draw(result.Page, result.Bounds.X, result.Bounds.Bottom + 10);
//draw string with returned bounds from table
element.Draw(result.Page, result.Bounds.X, result.Bounds.Bottom + 10);
MemoryStream stream = new MemoryStream();
//Saves the document.
doc.Save(stream);
doc.Close(true);
Sample link: http://www.syncfusion.com/downloads/support/directtrac/171058/ze/App2938608856
Please let us know if you need any further assistance.

Add and display FixedDocument to WPF form

I'm programmatically generating a FixedDocument to help me print. FixedDocument.ActualWidth is coming out as 0. I suspect this is because I am not actually displaying the FixedDocument. How can I add and display a FixedDocument object?
This is a beginner question. I'm not skilled with WPF. I looked on MSDN/Goog. Sites make the assumption that I've already added the FixedDocument and just need to manipulate it.
I have:
private FixedDocument CreateFixedDocumentWithPages()
{
FixedDocument fixedDocument = CreateFixedDocument();
fixedDocument.DocumentPaginator.PageSize = size;
PageContent content = AddContentFromImage();
fixedDocument.Pages.Add(content);
return fixedDocument;
}
Pseudocode of what I want: myWpfFormObject.AddChild(fixedDocument)
for show FixedDocument:
in your Wpf window, add the DocumentViewer Controle, then set the Document property.
for ActualWidth pb:
I think you should call the methods Measure & Arrange for each FixedPage.
See the code below from the exapmle in msdn:
Size sz = new Size(8.5 * 96, 11 * 96);
fixedPage.Measure(sz);
fixedPage.Arrange(new Rect(new Point(), sz));
fixedPage.UpdateLayout();
see also https://stackoverflow.com/a/1695518/1271037
So I had a slightly different situation, but this answer got me close. I'm using the fixed document to display Tiffs from a scanner. Some of those Tiffs can be in legal letter format (so longer than the standard A4 8.5 by 11 size). The code below fixed my issue and this answer helped.
So ended up I'm taking a fixed document, creating a page content, creating a fixed page, creating an image.
Then taking the image and adding it to the fixed page, then taking the fixed page and adding it to the page content, then taking the page content and adding it to the fixed document.
System.Windows.Documents.FixedPage fixedPage = new System.Windows.Documents.FixedPage();
System.Windows.Documents.PageContent pageContent = new System.Windows.Documents.PageContent();
pageContent.Child = fixedPage;
if (fixedDocument == null)
{
fixedDocument = new System.Windows.Documents.FixedDocument();
}
fixedDocument.Pages.Add(pageContent);
System.Windows.Controls.Image image = new System.Windows.Controls.Image();
TiffBitmapDecoder decoder = new TiffBitmapDecoder(new Uri(tiffImage, UriKind.Relative), BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnDemand);
image.Source = decoder.Frames[0];
fixedPage.Children.Add(image);
//Code to make the legal letter size work.
Size sz = new Size(decoder.Frames[0].Width, decoder.Frames[0].Height);
fixedPage.Width = sz.Width;
fixedPage.Height = sz.Height;
pageContent.Width = sz.Width;
pageContent.Height = sz.Height;

ITextSharp Defining a Pages Background Image: Whats the correct way?

Is it possible to set a background image for a pdf page in ITextSharp?
Whats the correct way to define a background image for a pdf page? Is there a property of the document I set?
Or is it just like creating another image(my image has the dimensions of a A4 page)? If I add the background image as a normal image will I be able to place paragraphs over the top of the background image?
var document = new Document(PageSize.A4, 50, 50, 25, 25);
// Create a new PdfWrite object, writing the output to a MemoryStream
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/test.jpg"));
logo.SetAbsolutePosition(0,0);
document.Add(logo);
// Will the following paragraph be ON TOP or below the background image?
// I am aiming for on top
document.Add( new Paragraph("sjfkkjdsfk") );
document.Close();
The logo is fine - it's just a regular image content on the page, not backgound img (like in HTML). To put content on top of that, you need to use Direct Content:
PdfContentByte over = writer.DirectContent;
over.SaveState();
over.BeginText();
over.SetFontAndSize(BaseFont.CreateFont(), 9);
over.ShowTextAligned(Element.ALIGN_LEFT, "Your Text", x, y, 0);
over.SetLineWidth(0.3f);
over.EndText();
over.RestoreState();
Please note the x and y cord are from the bottom left corner. The last parameter is for rotation.
Another tip: do a doc.NewPage(); if you want to start a new page with the image background, so the the text cord is on the new page.

Categories