I try to get PdfSharp working in an Azure Function
But I have some problems with fonts
// Create a new PDF document
PdfDocument document = new PdfDocument();
document.Info.Title = "Created with PDFsharp";
// Create an empty page
PdfPage page = document.AddPage();
// Get an XGraphics object for drawing
XGraphics gfx = XGraphics.FromPdfPage(page);
// Create a font
XFont font = new XFont("Verdana", 20, XFontStyle.BoldItalic);
// Draw the text
gfx.DrawString("Hello, World!", font, XBrushes.Black,
new XRect(0, 0, page.Width, page.Height),
XStringFormats.Center);
This is also the code from the PDFSharp sample page...
At the font line he gives me the following error...
Exception while executing function: Functions.PDFGenerationFunction. PdfSharp: Internal error. Font data could not retrieved.
Do I need to reference something special? Or is it just not possible to do this in an Azure function?
PDFSharp version --> "PDFsharp" : "1.32.3057"
And/Or another solution to generate a PDF document in an Azure Function...
This is likely an issue with the sandbox that Azure Functions and webapps run in.
Check out this list for known PDF libraries that will work in the sandbox.
https://github.com/projectkudu/kudu/wiki/Azure-Web-App-sandbox#unsupported-frameworks
PDF Sharp is unable to find an appropriate font for the function and also for Web APIs/Apps. Because they are not provided with the standard fonts.
To resolve this one needs to code and provide a font resolver based on the PDFSharp interface IFontResolver to PDF Sharp. That resolver will actually acquire the font and return it as a stream.
The below example is a resolver I wrote to extract from the current assemblies embeded fonts such as:
PdfSharp.Fonts.GlobalFontSettings.FontResolver = new EmbeddedFontResolver();
The best example on how to create such a resolver on Stack Overflow is this answer (it is not my answer, but I have modified it to provide a better understanding of what happens)
Azure PDF Sharp not using Unicode font
If the function won't allow you to use embeded fonts, you can load them most likely from an Azure Blob.
Related
Google has somewhat recently rolled out the ability to insert audio files from your Drive into Slides with various playback options.
I cannot find any documentation on how to insert a file through Google Scripts but can do so going through the available menu options. I tried using the insertVideo method but got an error
"Exception: The parameters (DriveApp.File) don't match the method signature for SlidesApp.Slide.insertVideo."
Here is a general function I'm trying to get to work (NOOB disclaimer goes here):
function uploadAudioToCurrentSlide(){
var presentation = SlidesApp.getActivePresentation();
var currentSlide = presentation.getSlides()[0];
var audioFile = DriveApp.getFileById('idofaudiofileindrive');
currentSlide.insertVideo(audioFile);
}
Any help is most appreciated!
You want to insert a audio file in Google Drive to Google Slides using Google Apps Script.
Issue and workaround:
I think that the reason of your issue is that the file object is directly used to the method of insertVideo. The argument of insertVideo is the URL and the video object which is not the file object. By this, such error occurs.
In the current stage, when the method of insertVideo is used, the video content is required to be the publicly shared YouTube URL.
And also, it seems that the audio file cannot be directly inserted.
Unfortunately, it seems that these are the current specification. So as a workaround, how about the following flow?
At first, convert the audio file to a video file like MP4. As a test, this can be done at other site. But I'm not sure about the file type of your audio file.
Insert the converted MP4 file on Google Drive using Slides API.
When the Slides API is used, you can insert the video file in Google Drive to the Google Slides. In this sample script, "CreateVideoRequest" of the batchUpdate method of Slides API is used.
Sample script:
Before you run the script, please enable Slides API at Advanced Google services.
function myFunction() {
var fileId = "###"; // Please set the file ID of the converted video file on Google Drive.
var presentation = SlidesApp.getActivePresentation();
var currentSlide = presentation.getSlides()[0];
var resource = {requests: [{createVideo: {source: "DRIVE", id: fileId, elementProperties: {pageObjectId: currentSlide.getObjectId()}}}]};
Slides.Presentations.batchUpdate(resource, presentation.getId());
}
Note:
When you can upload the audio file to YouTube and publicly share it, you can use your script using the URL of the YouTube.
References:
insertVideo(videoUrl)- Advanced Google services
Method: presentations.batchUpdate
CreateVideoRequest
My application allows the user to upload images and send them to the service, which then converts it to another format and sends it back. We are adding support for the SVG file format and I am running into an issue with reading the file from a byte array.
The issue is that when I initialize a MagickImageInfo object with the SVG Stream object, I get this error:
"no decode delegate for this image format '' # error/blob.c/BlobToImage/355"
I played around with it and am able to get past this error if I instead create a MagickImage object and supply it with an instance of MagickReadSettings where I set the Format to SVG explicitly.
The core problem is that the MagickImage code needs a hint as to what kind of file it is when it's an SVG. For other file types, it seems to be able to infer what kind of file it is. However, while I am able to supply the MagickImage class with what format the file is, the MagickImageInfo class doesn't have any parameters that I can give it to hint at the file type.
One possible solution would be to write the file to disk, then have MagickImageInfo class read the file from disk, but I really don't want to do this as it adds complexity to the service and makes it depend on disk write access.
Relevant code:
Working code:
var readSettings = new MagickReadSettings() { Format = MagickFormat.Svg };
using (MagickImage image = new MagickImage(stream, readSettings))
{
image.Write("C:\test"); // Actual code doesn't write to disk
}
Not working code:
MagickImageInfo info = new MagickImageInfo(stream);
It appears that you found a missing feature. I found your post here and added an extra overload for the MagickImageInfo constructor. The following will be available in Magick.NET 7.0.3.9 and higher:
var readSettings = new MagickReadSettings() { Format = MagickFormat.Svg };
MagickImageInfo info = new MagickImageInfo(stream, readSettings);
Feel free to open an issue next time here: https://github.com/dlemstra/Magick.NET or here: https://magick.codeplex.com/discussions
I generate pdf file from a HTML-page via jspdf plugin addHTML.
It works but the rendered text / font is really blurry, the original HTML page is not. Rendered images are fine, only text is the problem (see attached images).
original_image: http://111900.test-my-website.de/stackoverflow/orig.jpg
blurry_image: http://111900.test-my-website.de/stackoverflow/blurry.jpg
I read all google results the last three days - maybe I am the only person in the world I have exact this problem?!?! :/
I added the following scripts in my code:
spdf.js
jspdf.plugin.from_html.js
jspdf.plugin.split_text_to_size.js
jspdf.plugin.standard_fonts_metrics.js
pdf generation code:
pdf.addHTML(document.getElementById("container"),10,15,function() {
var string = pdf.save(filename);
});
Is there a quality option in jspdf I missed?
How can I render the font?
Thanks for reply,
Thomas
I found that when creating a PDF and the text was blurred when using addHtml this was because of the width of the web page. Try using it with the browser not maximised as a test.
My solution was to add some styles to adjust the width before calling addHTML with a width parameter that matches the styles I added. I then remove the additional styles in the function that runs after addHTML.
I had the same problem and I resolved it.
Actually, the main issue here is to specify the 'dpi' to avoid having a blurred image. In addition to that, try to avoid any 'smoothening' features beacuse it may make it worse. I have taken a look around the API and other discussion about it and I came back with the following solution:
1- update your version of html2canvas : many blurring issues have been fixed after the 1.0.0-alpha release.
2- use the following properties :
const context = canvas.getContext('2d');
context.scale(2, 2);
context['dpi'] = 144;
context['imageSmoothingEnabled'] = false;
context['mozImageSmoothingEnabled'] = false;
context['oImageSmoothingEnabled'] = false;
context['webkitImageSmoothingEnabled'] = false;
context['msImageSmoothingEnabled'] = false;
When creating a SVG image you have to set width,height and position otherwise it will not be rendered.
How do I read them from the original image?
Using Dart I first load the html image and after it's loaded I get the size and then define the SVG image and use the info I got before. This is a bit cumbersome and I wondered if there is another way.
The dart code looks like this:
ImageElement img = new ImageElement(src:'2.jpg'); //401x600
img.onLoad.listen((e) {
svg.ImageElement image = new svg.ImageElement();
image.setAttribute('x', '0');
image.setAttribute('y', '0');
image.setAttribute('width', img.width.toString());
image.setAttribute('height', img.height.toString());
image.getNamespacedAttributes('http://www.w3.org/1999/xlink')['href'] = '2.jpg';
});
There seems not to be a more convenient method (also not in JavaScript except when you use jQuery or another framework that includes methods for this).
Just create a method yourself and reuse that method for each image you load.
I've managed to make a WritableImage using
WritableImage snapshot = obj.getScene().snapshot(null);
Now I would like to output this screenshot on a pdf file. I've already managed to output text to a pdf using Apache pdfbox library using the following code:
PDDocument doc = null;
PDPage page = null;
try{
doc = new PDDocument();
page = new PDPage();
doc.addPage(page);
PDFont font = PDType1Font.HELVETICA_BOLD;
PDPageContentStream content = new PDPageContentStream(doc, page);
content.beginText();
content.setFont( font, 12 );
content.moveTextPositionByAmount( 100, 700 );
content.drawString("Hello World");
content.endText();
content.close();
doc.save("PDFWithText.pdf");
doc.close();
} catch (Exception e){
System.out.println(e);
}
How can I do this when using WritableImage rather that using basic String texts?
Also, how can I take a screenshot of certain nodes within a scene?
Thanks
Taking a screenshot of a scene
You already have working code for this in your question.
WritableImage snapshot = stage.getScene().snapshot(null);
Taking a screenshot of a . . . portion of a scene in JavaFx 2.2
Taking a snapshot of Node is similar to taking snapshot of a Scene, you just use the snapshot methods on the Node rather than the scene. First place your Node in a Scene, and then snapshot the Node.
WritableImage snapshot = node.snapshot(null, null);
The first parameter which may be passed to the node.snapshot call is some configuration for SnapshotParameters (which you probably don't need, but you can investigate them to see if they are required or useful for your case).
Now I would like to output this screenshot on a pdf file. How can I do this when using WritableImage rather that using basic String texts?
I have not used the pdfbox toolkit you reference in your question. Likely the toolkit works with awt based images rather than JavaFX images, so you will need to convert your JavaFX snapshot image to an awt buffered image using SwingFXUtils.fromFXImage.
To actually get the awt encoded image into a pdf file, consult the documentation for your pdfbox toolkit. Kasas's answer to Add BufferedImage to PDFBox document would seem to provide a code snippet for this operation. Looks like the relevant code (and I haven't tried this) is:
PDPageContentStream content = new PDPageContentStream(doc, page);
PDXObjectImage ximage = new PDJpeg(doc, bufferedImage);
content.drawImage(ximage, x, y);