How can I Copy top half of PDF and insert into new PDF - pdf-generation

I have an 8.5" x 11" PDF. I'd like to take the top 1/2 of the page, cut it and insert into page 1 of a new PDF. Then, take the bottom 1/2 of the page and insert it into page 2 of the PDF.
I'm essentially trying to split the PDF page in half... All docs I see relate to splitting the individual pages into separate files. I want to essentially copy part of the page and paste it into another doc.
Any help in providing direction using itextsharp? I have used it before and understand the concepts. But, am having a tough time. I'm sure I'll use the rectangle and use the coordinates.

It seems that you are looking to tile a PDF. You're not telling us which version of iText you plan on using. Since you seem to be new at this, I'm assuming that you're using iText 7. In that case, please consult Chapter 6 of the iText 7 Jump-Start tutorial where we tile a PDF with a single page into a PDF with four pages.
Original PDF:
Tiled PDF:
See TheGoldenGateBridge_Tiles for the code:
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
PdfDocument sourcePdf = new PdfDocument(new PdfReader(src));
PdfPage origPage = sourcePdf.getPage(1);
PdfFormXObject pageCopy = origPage.copyAsFormXObject(pdf);
Rectangle orig = origPage.getPageSize();
//Tile size
Rectangle tileSize = PageSize.A4.rotate();
AffineTransform transformationMatrix = AffineTransform.getScaleInstance(
tileSize.getWidth() / orig.getWidth() * 2f,
tileSize.getHeight() / orig.getHeight() * 2f);
//The first tile
PdfPage page = pdf.addNewPage(PageSize.A4.rotate());
PdfCanvas canvas = new PdfCanvas(page);
canvas.concatMatrix(transformationMatrix);
canvas.addXObject(pageCopy, 0, -orig.getHeight() / 2f);
//The second tile
page = pdf.addNewPage(PageSize.A4.rotate());
canvas = new PdfCanvas(page);
canvas.concatMatrix(transformationMatrix);
canvas.addXObject(pageCopy, -orig.getWidth() / 2f, -orig.getHeight() / 2f);
//The third tile
page = pdf.addNewPage(PageSize.A4.rotate());
canvas = new PdfCanvas(page);
canvas.concatMatrix(transformationMatrix);
canvas.addXObject(pageCopy, 0, 0);
//The fourth tile
page = pdf.addNewPage(PageSize.A4.rotate());
canvas = new PdfCanvas(page);
canvas.concatMatrix(transformationMatrix);
canvas.addXObject(pageCopy, -orig.getWidth() / 2f, 0);
// closing the documents
pdf.close();
sourcePdf.close();
Changing this example into code that tiles a PDF with 1 page into a PDF with 2 pages, is a matter of using some simple Math.
If you're using iText 5, then the question was already answered many times before. See for instance:
Tiling with iText, and adding margins
Tile PDF pages vertically with iTextSharp
How to tile a pdf to multiple pages with a border

Related

iText 7 - How to fill a canvas rectangle with a transparent color

In iText 7.1.9 I am taking a pdf created programmatically (not via iText) and need to apply a transparent rectangle along the left side and bottom to ensure the no content exists within a predefined clear zone (for print).
The below code places the yellow rectangles correctly but the desired result is the for the yellow fill to be semi-transparent or not 100% opaque so that visual inspection will show the content that that intersects with the rectangle instead of the rectangle clipping the content.
var page = pdf.GetPage(1);
PdfCanvas canvas = new PdfCanvas(page);
canvas.SaveState();
canvas.SetFillColor(iText.Kernel.Colors.ColorConstants.YELLOW);
var pageHeight = page.GetPageSize().GetHeight();
var pageWidth = page.GetPageSize().GetWidth();
// left side
canvas.Rectangle(0, 0, 15, pageHeight);
// bottom
canvas.Rectangle(0, 0, pageWidth, 15);
canvas.Fill();
canvas.RestoreState();
I attempted to use a TransparentColor but canvas.SetFillColor won't accept a TransparentColor, are there any other options?
When we speak about low-level content stream instructions, color itself and transparency levels are specified separately in PDF syntax. The TransparentColor class that you speak about was designed to simplify lives of users who are less familiar with nuances of PDF syntax, but it it a higher-level class that you can use e.g. in layout module, and in your case you operate with the document on quite low level.
Long story short, to set color transparency you only need one additional line next to setting the color itself:
canvas.SetExtGState(new PdfExtGState().SetFillOpacity(0.5f));
So the code becomes:
var page = pdf.GetPage(1);
PdfCanvas canvas = new PdfCanvas(page);
canvas.SaveState();
canvas.SetFillColor(iText.Kernel.Colors.ColorConstants.YELLOW);
canvas.SetExtGState(new PdfExtGState().SetFillOpacity(0.5f));
var pageHeight = page.GetPageSize().GetHeight();
var pageWidth = page.GetPageSize().GetWidth();
// left side
canvas.Rectangle(0, 0, 15, pageHeight);
// bottom
canvas.Rectangle(0, 0, pageWidth, 15);
canvas.Fill();
canvas.RestoreState();

Itext7 - Crop Image

Hi How can we resize image in iText 7 .
I am not able to find PDFTemplate in itext 7 now which used to crop image.
.
public Image cropImage(PdfWriter writer, Image image, float leftReduction, float rightReduction, float topReduction, float bottomReduction) throws DocumentException {
float width = image.getScaledWidth();
float height = image.getScaledHeight();
PdfTemplate template = writer.getDirectContent().createTemplate(
width - leftReduction - rightReduction,
height - topReduction - bottomReduction);
template.addImage(image,
width, 0, 0,
height, -leftReduction, -bottomReduction);
return Image.getInstance(template);
}
This is used for itext 5
Suppose that you have this image, measuring 900 x 1200 pixels:
But you only want to show part of this image (e.g. the ping pong balls):
Then you can use this iText 7 code:
PdfDocument pdf = new PdfDocument(new PdfWriter("cropimage.pdf"));
Document document = new Document(pdf);
Image image = new Image(ImageDataFactory.create(imagePath));
image.setFixedPosition(-20, -320);
Rectangle rectangle = new Rectangle(300, 300);
PdfFormXObject template = new PdfFormXObject(rectangle);
Canvas canvas = new Canvas(template, pdf);
canvas.add(image);
Image croppedImage = new Image(template);
document.add(croppedImage);
document.close();
We create an Image instance with the full image, and we set the fixed position in such a way that we chip off 20 pixels from the left, and 320 from the bottom.
We create a rectangle of 300 x 300 user units. This defines the size of the cropped image.
We create a PdfFormXObject using this rectangle. In iText 5 language, a Form XObject used to be named a PdfTemplate.
We create a Canvas object with this template, and we add the image to the canvas.
Finally, we create another Image using the template. The Canvas operation will have added the full image to that template, but it will be cropped to the size of the rectangle.
You can add this croppedImage to the document.

Rotate paragraphs or cells some arbitrary number of degrees -- Itext

I have a web site where the users upload photos and create photobooks. Also, they can add text at absolute positions, rotations, and alignments. The text can have new lines.
I've been using the Itext Library to automatize the creation of the Photobooks High Quality Pdfs that are printed latter on.
Adding the user uploaded images to the PDFs was really simple, the problem comes when I try to add the text.
In theory what I would need to do, is to define a paragraph of some defined width and height, set the users text, font, font style, alignment (center, left, right, justify), and finally set the rotation.
For what i've read about Itext, i could create a paragraph set the user properties, and use a ColumnText Object to set the absolute position, width and height. However it's not possibly to set the rotation of anything bigger than single line.
I can't use table cells either, because the rotation method only allow degrees that are multiples of 90.
Is there a way to add a paragraph with some rotation (say 20 degrees) without having to add the text line by line using the ColumnText.showTextAligned() method and all math that involves?
---- Edit: 08-Ago-2013 ----
If it helps anyone, this is the code I used to solve this problem (thanks to Bruno):
//Create the template that will contain the text
PdfContentByte canvas = pdfWriter.getDirectContent();
PdfTemplate textTemplate = canvas.createTemplate(imgWidth, imgHeight); //The width and height of the text to be inserted
ColumnText columnText = new ColumnText(textTemplate);
columnText.setSimpleColumn(0, 0, imgWidth, imgHeight);
columnText.addElement(paragraph);
columnText.go();
//Create de image wraper for the template
Image textImg = Image.getInstance(textTemplate);
//Asign the dimentions of the image, in this case, the text
textImg.setInterpolation(true);
textImg.scaleAbsolute(imgWidth, imgHeight);
textImg.setRotationDegrees((float) -textComp.getRotation()); //Arbitrary number of degress
textImg.setAbsolutePosition(imgXPos, imgYPos);
//Add the text to the pdf
pdfDocument.add(textImg);
Create a PdfTemplate object; just a rectangle.
Draw your ColumnText on this PdfTemplate; don't worry about the rotation, just fill the rectangle with whatever content you want to add to the column.
Wrap the PdfTemplate inside an Image object; this is just for convenience, to avoid the math. This doesn't mean your text will be rasterized.
Now apply a rotation and an absolute position to the Image and add it to your document.
Your problem is now solved ;-)
PS: I'm the author of the iText in Action books.
thanks to both our friends (Bruno & BernalCarlos)
my final code for users that use "RTL" in their projects is here :
// step 1
Document document = new Document();
document.setPageSize(PageSize.A4);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(destination_file));
CreateBorder event = new CreateBorder();
writer.setPageEvent(event);
// step 3
document.open();
// step 4
int imgWidth=400;
int imgHeight=50;
//Create the template that will contain the text
PdfContentByte canvas = writer.getDirectContent();
PdfTemplate textTemplate = canvas.createTemplate(imgWidth, imgHeight);
//The width and height of the text to be inserted
ColumnText columnText = new ColumnText(textTemplate);
columnText.setSimpleColumn(0, 0, imgWidth, imgHeight);
columnText.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
columnText.addElement(new Paragraph("محاسبه بار غیر متعادل", font_IranSemiBold));
columnText.go();
//Create de image wraper for the template
Image textImg = Image.getInstance(textTemplate);
//Asign the dimentions of the image, in this case, the text
textImg.setInterpolation(true);
textImg.scaleAbsolute(imgWidth, imgHeight);
textImg.setRotationDegrees(90); //Arbitrary number of degress
textImg.setAbsolutePosition(50, 200);
//Add the text to the pdf
document.add(textImg);
// step 5
document.close();

How can I add an image to a PDF at specific x-y coordinates using IText?

I have existing PDFs to which I need to dynamically add an image/images. The image comes from a file upload. Once I have the file uploaded, how can specify where to place the image on the PDF. One code snippet I found does not work correctly. This needs to work for PDFs with any number of pages. From what I understand, absolute positioning is set from the bottom-left corner of the last page of the PDF. If I need an image to be displayed 30 pixels from the top and 50 pixels from the left of page 1, how can I accomplish this? Or, if I need to display an image 50px from the top/100 px from the left on page 2?
I've tried using the code found at http://rip747.wordpress.com/2009/03/26/add-an-image-dynamically-to-a-pdf-with-cf-and-itext/. I've modified it for my needs below:
<cfscript>
myLeft = 30;
myTop = 50;
myPageNum = 1;
// output buffer to write PDF
fileIO = createObject("java","java.io.FileOutputStream").init(myOutputPath);
// reader to read our PDF
reader = createObject("java","com.lowagie.text.pdf.PdfReader").init(mySourcePath);
// stamper so we can modify our existing PDF
stamper = createObject("java","com.lowagie.text.pdf.PdfStamper").init(reader, fileIO);
// get the content of our existing PDF
content = stamper.getOverContent(reader.getNumberOfPages());
// create an image object so we can add our dynamic image to our PDF
image = createobject("java", "com.lowagie.text.Image");
// initalize our image
img = image.getInstance(imgPath);
x = (reader.getPageSize(1).width() - img.scaledWidth()) - myLeft;
y = (reader.getPageSize(1).height() - img.scaledHeight()) - myTop;
// now we assign the position to our image
img.setAbsolutePosition(javacast("float", x), javacast("float", y));
// add our image to the existing PDF
content.addImage(img);
// flattern our form so our values show
stamper.setFormFlattening(true);
// close the stamper and output our new PDF
stamper.close();
// close the reader
reader.close();
</cfscript>
The above code places my image at the top-right corner of page 2 - 50px form the top/30px from the left.
I know I'm close...just need a little help getting this nailed down for my needs.
I've updated my code. This gets the image to the top left corner of page 2 - correct positioning, but I want it on page 1:
x = myLeft;
y = (reader.getPageSize(1).height()) - img.scaledHeight() - myTop;
I thought maybe I needed to add the height of page 1 to get the image up to page 1, but the image completely disappears when I try either of the options below:
// I figure I'll need something like this to handle multi-page docs
y = (reader.getPageSize(1).height() * reader.getNumberOfPages()) - img.scaledHeight() - myTop;
y = reader.getPageSize(1).height() + reader.getPageSize(1).height() - img.scaledHeight() - myTop;
You're getting your "OverContent" from stamper.getOverContent(reader.getNumberOfPages());. The parameter for getOverContent() is the page number. So your code is getting a PdfContentByte for the last page, not the first.
I found my answer:
The page number has to be set in com.lowagie.text.pdf.PdfStamper.getOverContent():
content = stamper.getOverContent(myPageNum);
Knew it was easy.
are you using CF8+? You can use
<cfpdf action="addWatermark" source="myPDF.pdf" image="myImage.jpg"
position="0,0" rotation="0" showOnPrint="true" opacity="10">

Photoshop Action to fill image to make a certain ratio

I am looking to make a photoshop action (maybe this isn't possible, any other application recommendations would be helpful as well). I want to take a collection of photos and make them a certain aspect ration, ex: 4:3.
So I have an image that is 150px wide by 200px high. What I would like to happen is the image's canvas is made to be 267px wide, with the new area filled with a certain color.
So there are two possibilities I can think of:
1) Photoshop actions could do this, but I would have to pull current height, multiply by 1.333333 and then put that value in the width box of the canvas resize. Is it possible to have calculated values in Photoshop actions?
2) Some other application has this feature built in.
Any help is greatly appreciated.
Wow, I see now (after writing the answer) that this was asked a long time ago. . . oh well. This script does the trick.
This Photoshop script will resize any image's canvas so that it has a 4:5 aspect ratio. You can change the aspect ratio applied by changing arWidth and arHeight. The fill color will be set to the current background color. You could create an action to open a file, apply this script, then close the file to do a batch process.
Shutdown Photoshop.
Copy this javascript into a new file named "Resize Canvas.jsx" in Photoshop's Presets\Scripts folder.
Start Photoshop and in the File - Scripts menu it should appear.
#target photoshop
main ();
function main ()
{
if (app.documents.length < 1)
{
alert ("No document open to resize.");
return;
}
// These can be changed to create images with different aspect ratios.
var arHeight = 4;
var arWidth = 5;
// Apply the resize to Photoshop's active (selected) document.
var doc = app.activeDocument;
// Get the image size in pixels.
var pixelWidth = new UnitValue (doc.width, doc.width.type);
var pixelHeight = new UnitValue (doc.height, doc.height.type);
pixelWidth.convert ('px');
pixelHeight.convert ('px');
// Determine the target aspect ratio and the current aspect ratio of the image.
var targetAr = arWidth / arHeight;
var sourceAr = pixelWidth / pixelHeight;
// Start by setting the current dimensions.
var resizedWidth = pixelWidth;
var resizedHeight = pixelHeight;
// The source image aspect ratio determines which dimension, if any, needs to be changed.
if (sourceAr < targetAr)
resizedWidth = (arWidth * pixelHeight) / arHeight;
else
resizedHeight = (arHeight * pixelWidth) / arWidth;
// Apply the change to the image.
doc.resizeCanvas (resizedWidth, resizedHeight, AnchorPosition.MIDDLECENTER);
}
Mind that the accepted answer from #user268911 may not work for you if the source image has different pixels/inch than 72. Because the UnitValue.convert function works correctly only with 72 px/inch. To be sure the conversion is correct for ever pixel/inch value, set baseUnit property as follows:
...
var pixelWidth = new UnitValue (doc.width, doc.width.type);
pixelWidth.baseUnit = UnitValue (doc.width.baseUnit, "in");
var pixelHeight = new UnitValue (doc.height, doc.height.type);
pixelHeight.baseUnit = UnitValue (doc.height.baseUnit, "in");
...
For more details about the conversion see "Converting pixel and percentage values" section of the Adobe JavaScript Tools Guide.
What languages do you know? ImageMagick has command line tools that can do this, but you'd need to know a scripting language to get the values and calculate the new ones.
For .NET, my company's product, DotImage Photo, is free and can do this (need to know C# or VB.NET)

Resources