I'm trying add picture on centre(middle) of page PDF file with text, but I can't do it right. I use for image SetAbsolutePosition, but text don't stand under picture.
I need in my Pdf file next format of page:
I use next code:
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
ITextEvents ev = new ITextEvents();
writer.PageEvent = ev;
doc.Open();
var paragraph = new Paragraph();
var paragraph1 = new Paragraph();
var chunk = new Chunk("Text under picture", f14nb);
var chunk1 = new Chunk("Code of picture", f14);
img = ScaleImg(Image.GetInstance(imgNane_2));
img.SetAbsolutePosition((PageSize.A4.Width - img.ScaledWidth) / 2,
((PageSize.A4.Height - img.ScaledHeight) / 2));
paragraph.Add(img);
paragraph1.Add(chunk);
paragraph1.Add(chunk1);
doc.Add(paragraph);
doc.Add(paragraph1);
doc.Close();
private Image ScaleImg(Image img)
{
if (img.Height > img.Width)
{
//Maximum height is 800 pixels.
float percentage = 0.0f;
percentage = 640 / img.Height;
img.ScalePercent(percentage * 100);
}
else
{
//Maximum width is 600 pixels.
float percentage = 0.0f;
percentage = 500 / img.Width;
img.ScalePercent(percentage * 100);
}
return img;
}
I think, that I should use another way for solve my problem, but I don't know which.
Thank you.
I understood how do it.
This is for image with text:
public Image getWatermarkedImage(Document Doc, Image img, String watermarkText)
{
float width = img.ScaledWidth;
float height = img.ScaledHeight;
PdfTemplate template = cb.CreateTemplate(width, height);
template.AddImage(img, width, 0, 0, height, 0, 0);
ColumnText.ShowTextAligned(template, Element.ALIGN_RIGHT,
new Phrase(watermarkText, fontBold_14), width - 10, 10, 0);
return Image.GetInstance(template);
}
This is for adding text under image(main code):
var codeOfPicture = "*Code of picture* - *Код картинки*";
var chunk = new Chunk("Text under picture", font_14);
img = ScaleImg(Image.GetInstance(imgNane_1));//imgNane_2));
var tmpImg = getWatermarkedImage(doc, img, codeOfPicture);
var textY = ((PageSize.A4.Height - img.ScaledHeight) / 2) - 15;
var textX = PageSize.A4.Width / 2;
tmpImg.SetAbsolutePosition((PageSize.A4.Width - img.ScaledWidth) / 2,
((PageSize.A4.Height - img.ScaledHeight) / 2));
doc.Add(tmpImg);
ColumnText.ShowTextAligned(cb, Element.ALIGN_CENTER, new Phrase(chunk), textX, textY, 0);
Related
I create a custom Pdf document in my application where among a lot of other things I print other images and pdfs inside it, recently I got a pdf document that contains two pages of an ID document, this pdf looks perfectly fine when it's viewed in Acrobat or another tool but when is printed in that other pdf via iTextSharp it's printed like an A4 page with the page in the right corner and a lot of white space, also worth to be noted I can print small sized Pdfs, also if I resize that pdf to a custom size, say 3in and 2inch it's displayed fine.
Below you'll find the code and the documents created and used:
Link of pdf documents: https://drive.google.com/drive/folders/1uj9fjhJd6JU1cZ-j3B74o6EZelUhUofH?usp=sharing
Images if you don't want to view pdfs online:
public static void AttachPdfDocument(DruckKontext<DruckDatenOhneErgebnis> druckKontext, string pdfBaseString, string docName,
Dictionary<string, List<KeyValuePair<string, string>>> fieldNamesAndValues)
{
try
{
//druckKontext.AddHigHighlightedTitle("Angehängtes Dokument: " + docName);
//druckKontext.PosY -= 90;
PdfReader reader = new PdfReader(Convert.FromBase64String(pdfBaseString));
PdfReader.unethicalreading = true;
byte[] newDoc = null;
using (MemoryStream streamTemplate = new MemoryStream())
{
using (PdfStamper pdfStamper = new PdfStamper(reader, streamTemplate))
{
pdfStamper.FormFlattening = true;
pdfStamper.Close();
}
newDoc = streamTemplate.ToArray();
}
reader = new PdfReader(newDoc);
PdfWriter writer = druckKontext.Writer;
PdfContentByte canvas = writer.DirectContent;
for (int p = 1; p <= reader.NumberOfPages; p++)
{
AddDocumentUploadHeaders(druckKontext, "I. Dokumentenuploads", docName + " (" + p + " / " + reader.NumberOfPages + ")", fieldNamesAndValues);
float pageWidth = druckKontext.DocumentStyle.RechterRand - 90;
float pageHeight = druckKontext.PosY - 100;
PdfImportedPage page = canvas.PdfWriter.GetImportedPage(reader, p);
Rectangle pagesize = reader.GetPageSizeWithRotation(p);
float oWidth = pagesize.Width;
float oHeight = pagesize.Height;
float scale = getScale(oWidth, oHeight);
float scaledWidth = oWidth * scale;
float scaledHeight = oHeight * scale;
int rotation = pagesize.Rotation;
var rect = new iTextSharp.text.Rectangle(550, 680, 30, 100);
rect.BackgroundColor = BaseColor.LIGHT_GRAY;
canvas.Rectangle(rect);
var x = 30 + (pageWidth / 2) - (scaledWidth / 2);
var y = 100 + (pageHeight / 2) - (scaledHeight / 2);
AffineTransform transform = new AffineTransform(scale, 0, 0, scale, 0, 0);
switch (rotation)
{
case 0:
transform = new AffineTransform(scale, 0, 0, scale, x, y);
canvas.AddTemplate(page, transform);
break;
case 90:
AffineTransform rotate90 = new AffineTransform(0, -1f, 1f, 0, x, scaledHeight + y);
rotate90.Concatenate(transform);
canvas.AddTemplate(page, rotate90);
break;
case 180:
AffineTransform rotate180 = new AffineTransform(-1f, 0, 0, -1f, scaledWidth + x, scaledHeight + y);
rotate180.Concatenate(transform);
canvas.AddTemplate(page, rotate180);
break;
case 270:
AffineTransform rotate270 = new AffineTransform(0, 1f, -1f, 0, scaledWidth + x, y);
rotate270.Concatenate(transform);
canvas.AddTemplate(page, rotate270);
break;
default:
canvas.AddTemplate(page, scale, 0, 0, scale, x, y);
break;
}
if (p < reader.NumberOfPages)
{
druckKontext.NewPageBeratungsdokumentation();
//druckKontext.PosY -= 40;
}
}
}
catch (Exception ex)
{
}
}
private static float getScale(float width, float height)
{
float scaleX = (float)((PageSize.A4.Width / width) * 0.7);
float scaleY = (float)((PageSize.A4.Height / height) * 0.7);
return Math.Min(scaleX, scaleY);
}
I am converting a multi-paged (paginated) pdf document into a single page (non-paginated) pdf document.
I am looking to overcome the 200 inch limitation in adobe reader.
With iTextSharp.PdfReader each page is read to create a total height of the target document and find the maximum width.
The code to create the document works ok reading directly from the paginated pdf into the non-paginated pdf. Utilizing Chrome or Foxit the file opens fine. Adobe gives the 200 inch truncation when the page exceeds 200 inchs. In my test file the page height is 8.25 x 814 inches.
Changing the UserUnits to 4.07 (814/200) has Adobe show the page height as 814in but still truncates the page as well as showing the width as 33.
If the width of the target file is set to width/userunits (8.25/4.07) the only left 2 inches are shown in the target file.
The copy part of the code:
RandomAccessFileOrArray ra = new RandomAccessFileOrArray(fn);
SizeF pageSize = new SizeF(pageWidth, pageHeight);
float USERUnitNewValue = ComputeUserUnit(pageSize);
if (pageHeight > 14400f)
{
USERUnitNewValue = pageHeight / 14400f;
}
float NewPageWidth = (pageWidth <= 14400f) ? pageWidth : pageWidth* USERUnitNewValue;
float NewPageHeight = pageHeight * USERUnitNewValue;
FileInfo file1 = new FileInfo(newfn);
DirectoryInfo directory1 = file1.Directory;
if (!directory1.Exists)
directory1.Create();
iTextSharp.text.Rectangle newPagesize = new iTextSharp.text.Rectangle(pageWidth, pageHeight);
Document newPdf = new Document(newPagesize);
PdfWriter writer = PdfWriter.GetInstance(newPdf, new FileStream(newfn, FileMode.Create));
writer.PdfVersion = PdfWriter.VERSION_1_6;
if (pageHeight > 14400)
{
writer.Userunit = USERUnitNewValue;
}
newPdf.SetMargins(0f, 0f, 0f, 0f);
newPdf.Open();
PdfContentByte cb = writer.DirectContent;
float verticalPosition = pageHeight;
for (int pagenumber = 1; pagenumber <= n1; pagenumber++)
{
if (pdfReader.NumberOfPages >= pagenumber)
{
verticalPosition = verticalPosition - pdfReader.GetPageSize(pagenumber).Height;
cb.AddTemplate(writer.GetImportedPage(pdfReader, pagenumber), 0, verticalPosition);
}
else
{
break;
}
}
newPdf.Close();
How can the original file be copied into the target where both files would keep the same size if someone sends it to a printer?
Yes there is some redundancy in this code as I have been troubleshooting this for a little while now.
The key question here is a setting that would maintain the 8.25 x 814in and still allow adobe to open the file.
Thanks,
Mike
Thank you David.
After looking through Mr Lowagie's document and brief note about addTemplate.
cb.addTemplate(page, scale, 0, 0, scale, 0, 0)
The code was updated to utilize the new userunit and scaling.
Opening ok in Adobe now and reporting page length as expected
Once again the code is a little ugly still
RandomAccessFileOrArray ra = new RandomAccessFileOrArray(fn);
SizeF pageSize = GetPageSize(fn);
PdfReader pdfReader = new PdfReader(fn);
float USERUnitNewValue = ComputeUserUnit(pageSize);
int n1 = pdfReader.NumberOfPages;
if (pageSize.Height > 14400f) //14400 value is 72 pixels per inch over 200 inches. 200 inches seems to be adobe limit to a page
{ //determine the userunit to be used
USERUnitNewValue = pageSize.Height / 14400f;
}
float NewPageWidth = (pageSize.Width <= 14400f) ? pageSize.Width / USERUnitNewValue : pageSize.Width / USERUnitNewValue;
float NewPageHeight = pageSize.Height / USERUnitNewValue;
FileInfo file1 = new FileInfo(newfn);
DirectoryInfo directory1 = file1.Directory;
if (!directory1.Exists)
directory1.Create();
iTextSharp.text.Rectangle newPagesize = new iTextSharp.text.Rectangle(NewPageWidth, NewPageHeight);
Document newPdf = new Document(newPagesize);
PdfWriter writer = PdfWriter.GetInstance(newPdf, new FileStream(newfn, FileMode.Create));
writer.PdfVersion = PdfWriter.VERSION_1_6;
if (pageSize.Height > 14400)
{
writer.Userunit = USERUnitNewValue;
}
newPdf.SetMargins(0f, 0f, 0f, 0f);
newPdf.Open();
PdfContentByte cb = writer.DirectContent;
float verticalPosition = NewPageHeight;
for (int pagenumber = 1; pagenumber <= n1; pagenumber++)
{
if (pdfReader.NumberOfPages >= pagenumber)
{
/*convoluted page position. First position should be 0,0
unlike other counters this starts as page 1 so we need to subtract the
first page height away so that we start at the bottom of the previous image
* hmm seems that ths AddTemplate feature adds the pages in reverse order or
* at least the coordinate system sets 0,0 at the bottom left of the page
*/
float widthfactor = 1 / USERUnitNewValue; //Page scaling (width)
float heightfactor = 1 / USERUnitNewValue; //Page scaling (height)
//vertical position needs to take into account the new page height taking new UserUnit in affect
verticalPosition = verticalPosition - (pdfReader.GetPageSize(pagenumber).Height / USERUnitNewValue);
cb.AddTemplate(writer.GetImportedPage(pdfReader, pagenumber), heightfactor, 0, 0, widthfactor, 0, verticalPosition);
}
else
{
break;
}
}
newPdf.Close();
Thank you again for your help,
Mike
When saving, the image has the right design but the PDF has the wrong text on it. Could you explain why the documents are different?
I'm also open to other solutions for saving a PDF of the whole document and the ability to print a selected page of a multi-page document.
thanks :)
EDIT: the image is showing the date ("24th May 2016") which is correct and what I want the PDF to show, but instead the PDF is showing "TEST TEST"
1
public static void pdf() {
DateTime now = DateTime.Now;
string filename = "MixMigraDocAndPdfSharp.pdf";
filename = Guid.NewGuid().ToString("D").ToUpper() + ".pdf";
PdfDocument document = new PdfDocument();
SamplePage1(document);
document.Save(filename);
Process.Start(filename);
}
2
static void SamplePage1(PdfDocument document) {
PdfPage page = document.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(page);
gfx.MUH = PdfFontEncoding.Unicode;
gfx.MFEH = PdfFontEmbedding.Default;
XFont font = new XFont("Verdana", 13, XFontStyle.Bold);
gfx.DrawString("TEST TEST", font, XBrushes.Black,
new XRect(100, 100, page.Width - 200, 300), XStringFormats.Center);
Document doc = new Document();
Section sec = doc.AddSection();
Paragraph para = sec.AddParagraph();
header("24th May 2016");
DocumentRenderer docRenderer = new DocumentRenderer(doc);
docRenderer.PrepareDocument();
docRenderer.RenderObject(gfx, XUnit.FromCentimeter(5), XUnit.FromCentimeter(10), "12cm", para);
PageInfo info = docRenderer.FormattedDocument.GetPageInfo(1);
int dpi = 150;
int dx, dy;
if (info.Orientation == PdfSharp.PageOrientation.Portrait) {
dx = (int)(info.Width.Inch * dpi);
dy = (int)(info.Height.Inch * dpi);
} else {
dx = (int)(info.Height.Inch * dpi);
dy = (int)(info.Width.Inch * dpi);
}
Image image = new Bitmap(dx, dy, PixelFormat.Format32bppRgb);
Graphics graphics = Graphics.FromImage(image);
graphics.Clear(System.Drawing.Color.White);
float scale = dpi / 72f;
graphics.ScaleTransform(scale, scale);
gfx = XGraphics.FromGraphics(graphics, new XSize(info.Width.Point, info.Height.Point));
docRenderer.RenderPage(gfx, 1);
gfx.Dispose();
image.Save("test.png", ImageFormat.Png);
doc.BindToRenderer(docRenderer);
docRenderer.RenderObject(gfx, XUnit.FromCentimeter(5), XUnit.FromCentimeter(10), "12cm", para);
Process.Start("mspaint", "test.png");
}
3
public static void header(String date) {
Paragraph paragraph = new Paragraph();
var dateIssued = firstPage.AddTextFrame();
dateIssued.Height = "1.0cm";
dateIssued.Width = "6.0cm";
dateIssued.Left = "2.1cm";
dateIssued.RelativeHorizontal = RelativeHorizontal.Margin;
dateIssued.Top = "3.55cm";
dateIssued.RelativeVertical = RelativeVertical.Page;
paragraph = dateIssued.AddParagraph(date);
}
You call docRenderer.RenderPage(gfx, 1); for the image only. This renders the header.
You do not call docRenderer.RenderPage(gfx, 1); for the PDF. So no date there, just the "TEST TEST" you draw earlier.
I'm working with pdfs, I'm merging them first and then creating a heading and a footer for every page of the merged pdf. I'm using one method to merge and a different one to set the header and footer.
For certain documents the header and footer overlaps with the content. I've tried to set margin for the document but it doesn't change anything.
public byte[] HeaderAndFooter(byte[] inputPdf)
{
var dest = new MemoryStream();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPdf.ToMemoryStream()),
new PdfWriter(dest));
Document doc = new Document(pdfDoc);
doc.SetMargins(200,200, 200, 200); /* It doesn't matter the
numbers I set in here the document remains the same...*/
numberOfPages = pdfDoc.GetNumberOfPages();
Paragraph header = new Paragraph("This is a header for every page...")
.SetFont(PdfFontFactory.CreateFont(FontConstants.HELVETICA))
.SetFontSize(10)
.SetFontColor(Color.BLACK);
for (int i = 1; i <= numberOfPages; i++)
{
var pageSize = pdfDoc.GetPage(i).GetPageSize();
float LeftMargin = 36;
float BottomMargin = 24;
float y = pageSize.GetTop() - 72;
float center = pageSize.GetWidth() / 2;
doc.ShowTextAligned(header, LeftMargin, y, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
doc.ShowTextAligned(footerL, LeftMargin, BottomMargin, i, TextAlignment.LEFT, VerticalAlignment.BOTTOM, 0);
doc.ShowTextAligned(footerC, center, BottomMargin, i, TextAlignment.CENTER, VerticalAlignment.BOTTOM, 0);
}
doc.Close();
return dest.ToArray();
}
How could I avoid the header and footer from overlapping with the content?
What I'm trying to do here is to add an image to a blank pdf. So far I've done it, but I want the image to be centered. How can I do this?
Here is my C# code:
using (MemoryStream ms = new MemoryStream())
{
Document doc = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(System.IO.Path.Combine(filepath, strFilename), FileMode.Create));
doc.AddTitle("Document Title");
doc.Open();
iTextSharp.text.Image image1 = iTextSharp.text.Image.GetInstance(#"C:\Users\Desktop\Winniethepooh.png");
image1.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
if (image1.Height > image1.Width)
{
//Maximum height is 800 pixels.
float percentage = 0.0f;
percentage = 700 / image1.Height;
image1.ScalePercent(percentage * 100);
}
else
{
//Maximum width is 600 pixels.
float percentage = 0.0f;
percentage = 540 / image1.Width;
image1.ScalePercent(percentage * 100);
}
//image1.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
doc.Add(image1);
doc.Close();
}
And this is the output:
https://drive.google.com/open?id=0BzaejXGgqBOAMzd0UlY2QWFXNms
What I want is that the image is centered on the page. Currently the image is on the top of the page.
I even set the image alignment, but why doesn't it center the image on the page?
You need to use SetAbsolutePosition() in order to center the image.
Just add the following to your code before you call doc.Add(image1);:
...
...
image1.SetAbsolutePosition((PageSize.A4.Width - image1.ScaledWidth) / 2, (PageSize.A4.Height - image1.ScaledHeight) / 2);
doc.Add(image1);
...
...
Hope this helps.