I am setting PDF/X conformance using iText.
Having trimbox and artbox is one of the requirement of PDF/X. How can it be set? Im using the following code to set page size,
pageSize = new com.lowagie.text.Rectangle(height, width);
document = new Document(pageSize, 0, 0, 0, 0);
Kindly Help.
Page boundaries can be set using the setBoxSize() method. For instance:
writer.setBoxSize("art", new Rectangle(36, 36, 559, 806));
writer.setBoxSize("trim", new Rectangle(36, 36, 559, 806));
I don't know when the setBoxSize() method was introduced, but I see my name in your code sample. When I see my name in your code, I know that you are using a version of iText that is obsolete and therefore unsupported. The last version with my name in the packages dates from July 2009. Please understand that those versions also can't be used in a commercial context because of IP issues that were discovered after those versions were released under the LGPL.
See Can iText 2.1.7 / iTextSharp 4.1.6 or earlier be used commercially? for more info.
Related
I have searched and searched and cannot find the answer to my problem. I've tried many different approaches in my code, but I've hit a wall and I'm not sure where to go from here. I seem to be wanting to do the same thing as these two threads:
Trying to insert an image into a pdf in c#
Add image in an existing PDF with itextsharp
They are very similar and the answer is the same. However, when I use that exact code, the result is a PDF without an image. Here is my code:
using (var existingFileStream = new FileStream(fileNameExisting, FileMode.Open))
using (var newFileStream = new FileStream(fileNameNew, FileMode.Create))
{
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, newFileStream, '\0', true);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (var field in form.Fields)
{
if (field.Key == "form1[0].ec_Bldg_Photo_1[0].ImageField2[0]")
{
PushbuttonField imageField = form.GetNewPushbuttonFromField(field.Key);
imageField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
imageField.IconReference = null;
imageField.ProportionalIcon = true;
imageField.Image = Image.GetInstance(#"PATH_TO_IMAGE\front.jpg");
form.ReplacePushbuttonField(field.Key, imageField.Field);
}
}
stamper.FormFlattening = false;
stamper.Close();
pdfReader.Close();
}
I have tried to rule out all of the obvious things. My path to the image is correct, the field is indeed a PushbuttonField when I read the existing PDF field and get the field type. If I open the PDF in Adobe Reader and click on the placeholder for the image, it allows me to pick a file from my PC. When I place an image in the file, save, and then read in that PDF, I can then change my code to this:
imageField.ProportionalIcon = false;
And now all of sudden the image is stretched on the saved copy. So I see that it is changing this part but this is when I enter the image manually in Adobe Reader. When I read in the field after I set that image in Adobe Reader and it shows correctly, I see a couple interesting things. The field.Image property IS NULL and the field.IconReference is NOT NULL. When I use the original code to try and insert the image, it is reversed, where Image is NOT NULL but IconReference IS NULL
Any help would be greatly appreciated, thank you!!
EDIT 1: Ok so I didn't see it the first time, but I went back and checked more thoroughly and I did find that key. Here it is:
Several things are at play here.
Usage Rights:
The PDF is digitally signed with a private key owned by Adobe.
You can see this using RUPS here (in your screen shot you didn't go deep enough):
This has two implications:
The signature unlocks special permissions in Adobe Reader, such as the permission to save a filled out form locally.
Making any changes to the original PDF breaks the signature and removes the special permissions leading to an ugly error message in Adobe Reader.
This functionality is deprecated in (and even removed from) PDF 2.0. It's old technology that became obsolete with the emergence of PDF viewers other than Adobe Reader.
My suggestion: remove the usage rights to avoid breaking the signature. See the FAQ entry "Why do I get an error saying that "use of extended features is no longer available"?" iText 7 / iText 5
This is the iText 7 code:
public void removeUsageRights(PdfDocument pdfDoc) {
PdfDictionary perms = pdfDoc.getCatalog().getPdfObject().getAsDictionary(PdfName.Perms);
if (perms == null) {
return;
}
perms.remove(new PdfName("UR"));
perms.remove(PdfName.UR3);
if (perms.size() == 0) {
pdfDoc.getCatalog().remove(PdfName.Perms);
}
}
This is the iText 5 code:
PdfReader reader = new PdfReader(old_file);
if (reader.hasUsageRights()) {
reader.removeUsageRights();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(new_file));
stamper.close();
}
reader.close();
This is the iText 5 answer.
Hybrid Form:
If you click on the /AcroForm entry, you see this:
There is a /Fields array with references to field dictionaries that are also widget annotations. That means that the document has an AcroForm form inside. However, there is also an /XFA entry with a series of XML snippets. That means that the document has an XFA form inside.
In other words: the same form description is added twice inside. You are changing a button in one form (the AcroForm part), but not in the other (the XFA form) and that leads to inconsistencies.
XFA has been deprecated in PDF 2.0 because there weren't many vendors supporting that technology. It's kind of frustrating to be confronted with forms that use deprecated technology.
My suggestion: I would remove the XFA part. See the FAQ entry "Is it safe to remove XFA?" iText 5 / iText 7
In iText 5, removing XFA is done like this:
AcroFields form = stamper.getAcroFields();
form.removeXfa();
Important: my suggestion is to remove all the deprecated functionality from the PDF, but if the government expects that functionality to be present, then you're out of luck. In that case, you will need to use Adobe software to process the form. If that's the case, you could complain to the government that their requirements lead to a de facto vendor lock-in. By the way: iText Software is also a vendor. It's an open source company that offers open source software under the AGPL license. The AGPL license allows free use under certain circumstances (see How do I make sure my software complies with AGPL: How can I use iText for free?) If you don't meet those requirements, you will have to purchase a commercial license for your use of iText.
I was migrating some code (originally using iText) to use PdfBox for PDF merging. All went fine except creating PDF packages or portfolios. I have to admit I was not aware that this existed until now.
this is a snippet of my code (using iText):
PdfStamper stamper = new PdfStamper(reader, out);
stamper.makePackage(PdfName.T);
stamper.close();
I need this but with PdfBox.
I'm looking into API and docs for both and I can not find a solution atm. Any help would be great.
PS. Sorry if I made impression that I need solution in iText, I need it in PdfBox because migration is going from iText to PdfBox.
As far as I know PDFBox does not contain a single, dedicated method for that task. On the other hand it is fairly easy to use existing generic PDFBox methods to implement it.
First of all, the task is effectively defined to do the equivalent to
stamper.makePackage(PdfName.T);
using PDFBox. That method in iText is documented as:
/**
* This is the most simple way to change a PDF into a
* portable collection. Choose one of the following names:
* <ul>
* <li>PdfName.D (detailed view)
* <li>PdfName.T (tiled view)
* <li>PdfName.H (hidden)
* </ul>
* Pass this name as a parameter and your PDF will be
* a portable collection with all the embedded and
* attached files as entries.
* #param initialView can be PdfName.D, PdfName.T or PdfName.H
*/
public void makePackage( final PdfName initialView )
Thus, we need to change a PDF (fairly minimally) to make it a portable collection with a tiled view.
According to section 12.3.5 "Collections" of ISO 32000-1 (I don't have part two yet) this means we have to add a Collection dictionary to the PDF catalog with a View entry with value T. Thus:
PDDocument pdDocument = PDDocument.load(...);
COSDictionary collectionDictionary = new COSDictionary();
collectionDictionary.setName(COSName.TYPE, "Collection");
collectionDictionary.setName("View", "T");
PDDocumentCatalog catalog = pdDocument.getDocumentCatalog();
catalog.getCOSObject().setItem("Collection", collectionDictionary);
pdDocument.save(...);
This is how I create a TextField in iText 5.
import com.itextpdf.text.pdf.TextField;
TextField tf = new TextField(stamper.getWriter(), rect, "fieldname");
tf.setText("fieldvalue");
tf.setBackgroundColor(BaseColor.WHITE);
tf.setBorderColor(BaseColor.BLACK);
tf.getTextField().setName("name_here");
stamper.addAnnotation(tf.getTextField(), 1);
This works. However, when I check in RUPS. PdfName.NM does not exist. setName() is the correct method, right?
You are assuming that methods can be chained in iText 5, but that assumption is wrong. We introduced chained methods only in iText 7.
In iText 5, you need to split things up:
PdfFormField ff = tf.getTextField();
ff.setName("name_here");
stamper.addAnnotation(ff, 1);
The PdfFormField isn't a member-variable of the TextField class, and getTextField() isn't a real getter. When you trigger getTextField(), a new PdfFormField instance is created (iText is open source, just check for yourself if you're not sure).
iText 5 grew organically. I don't have a degree in computer sciences; I am self-taught in programming. If you look at the evolution of iText, you can see how my programming skills improved. If you want a really clean version of iText, please use iText 7.
I want to extract text from an PDF document page wise and I am using itext. I used the example code from their website:
PdfReader reader = new PdfReader(pathToFile);
PdfReaderContentParser parser = new PdfReaderContentParser(reader);
TextExtractionStrategy strategy = parser.processContent(page, new SimpleTextExtractionStrategy());
The method processContent gives me a NullPointerException. What did I do wrong?
This is the stacktrace I get when using version 5.5.0 with this file:
java.lang.NullPointerException
at com.itextpdf.text.pdf.parser.PdfReaderContentParser.processContent(PdfReaderContentParser.java:82)
at com.itextpdf.text.pdf.parser.PdfReaderContentParser.processContent(PdfReaderContentParser.java:105)
at org.languageresources.PDFExtraktor.extractTextFromPage(PDFExtractor.java:100)
Given the code sniplet and sample document you gave I tried to reproduce the issue but to no avail, text extraction worked fine.
Furthermore, the stacktrace given:
java.lang.NullPointerException
at com.itextpdf.text.pdf.parser.PdfReaderContentParser.processContent(PdfReaderContentParser.java:82)
at com.itextpdf.text.pdf.parser.PdfReaderContentParser.processContent(PdfReaderContentParser.java:105)
at org.languageresources.PDFExtraktor.extractTextFromPage(PDFExtractor.java:100)
does not match the alleged version 5.5.0 because PdfReaderContentParser.java:82 in that version is an empty line and PdfReaderContentParser.java:105 does not exist: Back then that file was only 85 lines in size.
Assuming, though, that you use the current version 5.5.9, the stacktrace makes sense, in that version PdfReaderContentParser.java:82 is the second of these lines:
PdfDictionary pageDic = reader.getPageN(pageNumber);
PdfDictionary resourcesDic = pageDic.getAsDict(PdfName.RESOURCES);
and pageDic indeed can be null if there is no page pageNumber.
Thus, please check that page, the page number in question, is between 1 and reader.getNumberOfPages() inclusive.
I am currently evaluating iTextSharp (5.5.8) for a business case that includes pdf signing. The signature must include the pades-epes signature-policy-identifier attribute. I cannot find documentation and or samples to include this attribute. So the question I have is, is iTextSharp capable of providing this attribute and if so how can it be added.
I hope won't be too late, but I added some changes to iTextSharp source code to support PAdES-EPES signatures. Here are an example of my code:
SignaturePolicyInfo spi = new SignaturePolicyInfo();
spi.PolicyIdentifier = "2.16.724.1.3.1.1.2.1.9";
spi.PolicyHash = "G7roucf600+f03r/o0bAOQ6WAs0=";
spi.PolicyDigestAlgorithm = "SHA-1";
spi.PolicyUri = "https://sede.060.gob.es/politica_de_firma_anexo_1.pdf";
MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CADES, spi);
You can take a look at: https://github.com/zinkpad/itextsharp
I hope this help you.
Unfortunately you did not show where in your code you got stuck.
If you are using MakeSignature.SignDetached, I'm afraid adding a policy identifier is not supported.
But you can always use MakeSignature.SignExternalContainer instead. This helper allows you to create the actual signature container to embed externally using e.g. BouncyCastle, so you can include any attribute you want while iText(Sharp) does all the rest.