PDFKit, Not able to open the pdf generated - pdf-generation

I am trying to generate a pdf using some texts of my own (and not a html page). I tried using PDFKit. I am able to generate the pdf but then I am not able to open it in Preview (It may be damaged or use a file format that Preview doesn’t recognize.)
Below is the code,
var fs = require('fs');
PDFDocument = require ('pdfkit');
var doc = new PDFDocument
// Embed a font, set the font size, and render some text
doc.text('Some text with an embedded font!', 100, 100)
// Add another page
doc.addPage()
.text('Here is some vector graphics...', 100, 100)
// Draw a triangle
doc.save()
.moveTo(100, 150)
.lineTo(100, 250)
.lineTo(200, 250)
.fill("#FF3300")
// Apply some transforms and render an SVG path with the 'even-odd' fill rule
doc.scale(0.6)
.translate(470, -380)
.path('M 250,75 L 323,301 131,161 369,161 177,301 z')
.fill('red', 'even-odd')
.restore()
// Add some text with annotations
doc.addPage()
.fillColor("blue")
.text('Here is a link!', 100, 100)
//.underline(100, 100, 160, 27, color: "#0000FF")
.link(100, 100, 160, 27, 'http://google.com/')
// Write the PDF file to disk
doc.pipe(fs.createWriteStream('out.pdf') );
doc.end
I might be missing something small. P

It was a silly mistake on my part. I should have used doc.end() instead of using doc.end and due to this the pdf was not getting generated properly.

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();

Creating a template image dynamically for OSX menu bar

I'm having trouble creating a template image for the OSX menu bar. As far as I can tell, it has to be a PDF image. To that end, I have:
var pageRect: CGRect = CGRectMake(0, 0, CGFloat(10), CGFloat(barHeight))
let pdfData: NSMutableData = CFDataCreateMutable(nil, 0)
let pdfConsumer = CGDataConsumerCreateWithCFData(pdfData as CFMutableDataRef)
let pdfContext = CGPDFContextCreate(pdfConsumer, &pageRect, nil)
Then I draw into the PDF:
CGPDFContextBeginPage(pdfContext, nil)
CGContextSetRGBFillColor (pdfContext, 1, 0, 0, 1)
CGContextFillRect (pdfContext, CGRectMake (0, 0, 200, 100 ))
CGPDFContextEndPage(pdfContext)
Then I try to create an NSImage:
let image = NSImage(data: pdfData)
And add it to the status item's image property:
button.image = image
However, this just isn't working. I have tried saving the image to disk and opening it, but get the message that the image is corrupted, so I suspect the error is in converting the pdfData into an NSImage, though I'm not totally confident of that. Anyway, any help would be appreciated.
A template image does not have to be a PDF. To make an instance of NSImage a template image, simply set its template property to true.
No matter the nature of the image (bitmap, PDF, whatever), the system will only make use of its alpha channel when it's a template image. The color channels are ignored.
The system will automatically mark an image loaded from a file as a template image if its filename-minus-extension ends with "Template". So, for example, fooTemplate.png or barTemplate.pdf.

Append Images to PNG via Rmagick

for add text to image I'm doing next-
canvas = Magick::Image.read("init.png").first
gc = Magick::Draw.new
gc.pointsize(12)
gc.text(5, 207, params['property_type'])
gc.draw(canvas)
canvas.write("#tst.png")
How I can add images to exist picture(imposed from above)?
I found solution.
canvas = Magick::Image.read("init.png").first
append_image = Magick::Image.read('another.png').first
canvas.composite!(append_image, 0, 0, Magick::OverCompositeOp)

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();

Draw Element's Contents onto a Canvas Element / Capture Website as image using (?) language

I asked a question on SO about compiling an image file from HTML. Michaël Witrant responded and told me about the canvas element and html5.
I'm looked on the net and SO, but i haven't found anything regarding drawing a misc element's contents onto a canvas. Is this possible?
For example, say i have a div with a background image. Is there a way to get this element and it's background image 'onto' the canvas? I ask because i found a script that allows one to save the canvas element as a PNG, but what i really want to do is save a collection of DOM elements as an image.
EDIT
It doesn't matter what language, if it could work, i'm willing to attempt it.
For the record, drawWindow only works in Firefox.
This code will only work locally and not on the internet, using drawWindow with an external element creates a security exception.
You'll have to provide us with a lot more context before we can answer anything else.
http://cutycapt.sourceforge.net/
CutyCapt is a command line utility that uses Webkit to render HTML into PNG, PDF, SVG, etc. You would need to interface with it somehow (such as a shell_exec in PHP), but it is pretty robust. Sites render exactly as they do in Webkit browsers.
I've not used CutyCapt specifically, but it came to me highly recommended. And I have used a similar product called WkHtmlToPdf, which has been awesome in my personal experience.
After many attempts using drawWindow parameters, that were drawing wrong parts or the element, I managed to do it with a two steps processing : first capture the whole page in a canvas, then draw a part of this canvas in another one.
This was done in a XUL extension. drawWindow will not work in other browsers, and may not work in a non-privileged context due to security reasons.
function nodeScreenshot(aSaveLocation, aFileName, aDocument, aCSSSelector) {
var doc = aDocument;
var win = doc.defaultView;
var body = doc.body;
var html = doc.documentElement;
var selection = aCSSSelector
? Array.prototype.slice.call(doc.querySelectorAll(aCSSSelector))
: [];
var coords = {
top: 0,
left: 0,
width: Math.max(body.scrollWidth, body.offsetWidth,
html.clientWidth, html.scrollWidth, html.offsetWidth),
height: Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight)
var canvas = document.createElement("canvas");
canvas.width = coords.width;
canvas.height = coords.height;
var context = canvas.getContext("2d");
// Draw the whole page
// coords.top and left are 0 here, I tried to pass the result of
// getBoundingClientRect() here but drawWindow was drawing another part,
// maybe because of a margin/padding/position ? Didn't solve it.
context.drawWindow(win, coords.top, coords.left,
coords.width, coords.height, 'rgb(255,255,255)');
if (selection.length) {
var nodeCoords = selection[0].getBoundingClientRect();
var tempCanvas = document.createElement("canvas");
var tempContext = tempCanvas.getContext("2d");
tempCanvas.width = nodeCoords.width;
tempCanvas.height = nodeCoords.height;
// Draw the node part from the whole page canvas into another canvas
// void ctx.drawImage(image, sx, sy, sLargeur, sHauteur,
dx, dy, dLargeur, dHauteur)
tempContext.drawImage(canvas,
nodeCoords.left, nodeCoords.top, nodeCoords.width, nodeCoords.height,
0, 0, nodeCoords.width, nodeCoords.height);
canvas = tempCanvas;
context = tempContext;
}
var dataURL = canvas.toDataURL('image/jpeg', 0.95);
return dataURL;
}

Resources