Erase content in pdf page with itext - java

Shortly, I want to erase the content of pdf page by background color without changing its page size. Here is more detail:
Says pdf page size is A4 paper, content can be texts or images, and the erased content is 1 cm spacing around (blue part)
I wonder is there any way to do this?
Update: my try with clipping path
// render text and image
//...
// then erase
PdfContentByte clipCB = pdfWriter.getDirectContent();
clipCB.saveState();
clipCB.setColorStroke(Color.WHITE);
clipCB.rectangle(100,100,600, 600);
clipCB.clip();
clipCB.newPath();
clipCB.restoreState();

There are a few options. The easiest thing to do would be to draw 4 rectangles in the background color around the edges. A more elegant approach would be to set a clipping path prior to rendering the page's contents.
Here's an example using a clipping path: http://www.java2s.com/Tutorial/Java/0419__PDF/Cliparegion.htm

Related

Add form fields to a rotated page in pdfBox

I have a requirement to add adobe form fields to an existing pdf.
The problem I encounter is when adding fields to a rotated page, the resulting form field text orientation is incorrect.
e.g. A page that is rotated 90 degrees clockwise, results in form field where the text is "vertical".
Is there a workaround to get form fields created with the correct orientation?
The appearance characteristics dictionary (/MK entry) of the widget has an /R entry where the rotation can be set. See e.g. this file.
PDAppearanceCharacteristicsDictionary fieldAppearance
= new PDAppearanceCharacteristicsDictionary(new COSDictionary());
fieldAppearance.setRotation(90);
widget.setAppearanceCharacteristics(fieldAppearance);
You may have to adjust your coordinates. To find the best coordinates, use PDFDebugger and hover at the place you want your field to be.
Update:
For checkmarks (and radio buttons) where the appearance stream is created by the user and not by PDFBox (as seen here or in the PDFBox example) you need to set the matrix yourself like this (for 90°):
yesAP.setMatrix(AffineTransform.getQuadrantRotateInstance(1, rect.getWidth(), 0));
The "1" here is for 90°. The translation needs to be adjusted for the other rotations.

itext - add png image with no border

I want to add the following png image to my pdf:
I use following code to do it:
Image img = PngImage.getImage(filename);
img.setBorder(Image.NO_BORDER);
img.setAlignment(Element.ALIGN_CENTER);
img.scaleAbsolute(width,height);
document.add(img);
The image contains a bar graph which has no outer border. When I add the image to my pdf, it shows an outer border, but only for the bottom, left and top sides:
I want to remove border in the pdf, but the above code, does not make that happen.
I am using iText-2.1.5.
In the comments, I claimed that your original image does have a border. You claim it doesn't have a border. Now that you've shared the image, we can check the facts to see who is right.
As it turns out, I was right. When I open the image in GIMP, I clearly see a transparent border:
Maybe you don't see it, because you are looking at the image in Paint or maybe you consider "transparent" and "white" to be the same color. Obviously that assumption is wrong.
I created a PDF containing the image you shared and when I open this PDF using iText RUPS, I see something like this:
PNG is not supported in ISO-32000-1 (aka the PDF specification), hence software that wants to introduce a PNG into a PDF file needs to convert that PNG to another format. In the case of iText, "normal" PNGs are converted to a bitmap with filter /FlateDecode.
In your case, you have a PNG with tranparency. In ISO-32000-1, transparent images are always stored as two images: you have the opaque image (in my screen shot, /Img1 with object number 2) and the image mask (in my screen shot, /Img0 with object number 1).
If you look closely at the image mask (the image that makes the opaque image transparent), you see that it's a black and white image that shows a very small border. This image is shown in the lower-right panel where it says "Stream" (this is where the image stream is rendered). This very small border is the transparent border we can also see in the GIMP (or other image viewers that support transparent images).
If this border is transparent, then why do you see it in a PDF viewer? Well, this border is treated as a line with zero width. In PDF viewers, a line with zero width is shown using the smallest width that can be shown on the device that is being used to view the PDF. If you zoom into the PDF, you'll notice that the width of the line remains constant.
Summarized: you claimed that your image didn't have any border, and that a border was added by iText. I have proven you wrong: the image does have a transparent border and iText correctly introduces this transparent border as a mask. The PDF viewer shows this border as a zero-width line in accordance with ISO-32000-1.
You can solve your problem by removing the transparent border in the original image. For example: I flattened the image using the GIMP. The result is this image:
This image no longer has a transparent border and when you introduce it into a PDF, no border is shown, and no mask is added to the PDF:

Get the Extreme right , left,top,bottom position of an image - Itext

I am setting a margin for a pdf and checking if the contents of the page are exceeding the margin.
I am easily able to do that if the contents of a page are just text.
Here s what I am doing:
I am using TextMarginFinder. I will set the left margin values of the pdf based on the book size. and check with the finder.getLlx(); since finder.getLlx(); will get me the left most position of a text in that page.
TextMarginFinder finder;
if(leftmar>=finder.getLlx())
{
errormargin=1; //left margin error
System.out.println("Page: "+i+"Margin Error:LeftMArginError ");
}
But this does not work in case if the page contains an image. Although the image goes outside of the margin, I am not getting the error with the above code since the finder.getLlx(); function seems to work only for texts.
Two Questions:
1) While looping through the pages in pdf, if there is an image in that page, how can I check if that particular page contains an image?
2) If it contains an image, how can I obtain its extreme positions?
Update after mkl suggestion
if(leftmar>=finder.getLlx())
{
errormargin=1; //left margin error
System.out.println("finder.getLlx() value ="+finder.getLlx()+", leftmar Value="+leftmar);
}
if(rightmar<= finder.getUrx()){
errormargin=1; //right margin error
System.out.println("finder.getUrx() value ="+finder.getUrx()+", rightmar Value="+rightmar);
}
if(margintop >= finder.getUry()){
errormargin=3; //top margin error
System.out.println("finder.getUry() value ="+finder.getUry()+", margintop Value="+margintop);
}
if(marginbottom >= finder.getLly()){
errormargin=3; //bottom margin error
System.out.println("finder.getLly() value ="+finder.getLly()+", marginbottom Value="+marginbottom);
}
This is more an answer to what the OP actually wanted, a way to retrieve the bounding box of all content on a page.
The OP already uses the iText TextMarginFinder render listener class to determine the bounding box of the text on page. In the context of this answer an analogous class MarginFinder has been developed which does not only consider text but also other kind of content, e.g. bitmap images and vector graphics.
Thus, replacing the use of TextMarginFinder by MarginFinder allows to find the bounding box of any content on the page.
Please be aware:
Any content is considered, the margin finder does not check whether the content makes a difference. E.g. think about white text, white bitmap areas, or white rectangles, all are considered content and, therefore, the bounding box encompasses such invisible content, too. Especially the latter example, white rectangles, might be a problem here or there as some software first paints a white rectangle over the whole page area.
Clipping paths are not considered. Thus, even content that never is drawn (because it is clipped away) makes the bounding box expand.
Page borders are not considered, either. Thus, off-page content like printer marks may make the bounding box expand even more.
The code calculating the bounding box for vector graphics is not correct: it simply returns the bounding box of all control points which in case of Bezier curves may be false. Its ignoring line widths and wedge types also results in somewhat-off coordinates.
Annotations are not considered. Thus, the resulting bounding box may be to small if annotations are expected to also be considered, e.g. for forms.
In spite of these shortcomings, the render listener usually returns correct results. If this is not enough, the class can be extended accordingly.
PS: Anyone who is interested in the original question may find answers in the MarginFinder render listener class and its use.

How to move location of svg on iText PDF?

I tried to insert svg image to pdf file.
But I don't know how to move svg position on iText PDF.
The image is always located in (0,0).
How to move svg image position on iText PDF?
For example, I want to locate on the right side more than this sample.
http://itextpdf.com/examples/iia.php?id=263
Taken from the example you mention:
PdfContentByte cb = writer.getDirectContent();
PdfTemplate map = cb.createTemplate(6000, 6000);
drawSvg(map, CITY);
cb.addTemplate(map, 0, 0);
The map object is a canvas that in this case measures 6000 by 6000 user units (by default 1 user unit = 1 point).
This canvas can be used as a Form XObject inside the PDF. In iText language, a Form XObject is known as a PdfTemplate object. You draw the SVG to this PdfTemplate, in which case the coordinates defined in the SVG are used.
Once you have drawn the SVG to the canvas, you can add the Form XObject (or PdfTemplate) to the PDF using the addTemplate() method.
The first parameter is the object itself (in the snippet the map object), the two other parameters are the coordinates (in this case (0, 0) as you already mentioned in your question).
In short, you almost answered your own question: you refer to an example with the line:
cb.addTemplate(map, 0, 0);
And you notice that The image is always located in (0,0).
Change the 0, 0 in the addTemplate() method and you change the location of the SVG image in your PDF.

Browsing PDF page content. Problem with color space and DPI

I am writing a program that would validate PDF file. I am using iText java library to get content of a file, but I have some problems with parsing it. I need to get info about color space and DPI of each image. How can I get info about position and dimensions of image in PDF? I tried to browse each XObject of PDF but I stuck, I cannot find any information about width and height of file in PDF.
Are there any other libraries which can help me?
Thank You for all answers and tips.
The image object in the PDF file stores only the Width and the Height of the image in pixels. In order to know the position and size of the image on the page, in PDF points, you have to execute the page content stream, to create a virtual rendering. The image is painted on the page using the 'Do' operator and its position and size are given by the current transformation matrix that is in place when the 'Do' operator is executed.
The DPI for a specific drawing instance is computed as 72*imageSizeInPixels/imageSizeInPoints, imageSizeInPoints being computed as described above.

Categories

Resources