While I have a workaround for this problem, I'd prefer to do it the way that I ran into this problem. Let me explain the context before getting to the problem:
I'm using a scanner to get virtual images which I want to use to create a PDF with each page being one single image. I got the working just fine using PDFsharp for creation of the PDF.
However; if I try to re-save the PDFsharp document, it ends up blanking all the previous pages, and then adding the new image.
For a little more context, I'm using ASP.NET Windows Forms, with NTwain for the scanning software, PDFsharp for creating the PDF, and PdfiumViewer to view the PDF on the Windows form.
I have a class-level variable for the document
PdfDocument document = new PdfDocument();
On image save, I simply save the image to a new page
var img = pictureBox1.Image;
PdfPage page = document.AddPage();
XGraphics gfx = XGraphics.FromPdfPage(page);
XImage image = XImage.FromGdiPlusImage(img);
gfx.DrawImage(image, 0, 0);
To render out the document, I copy the document (thought this might fix the problem) to a new document, save the contents to a new memory stream, and simply view the PDF
var viewDocument = (PdfDocument)document.Clone();
MemoryStream ms = new MemoryStream();
viewDocument.Save(ms, false);
ms.Position = 0;
var pdf = PdfiumViewer.PdfDocument.Load(ms);
pdfRenderer1.Load(pdf);
I got it working by saving the image to a list, instead of as a new page, and remade the document each time I wanted to display it. The issue is really strange, however.
Any help understanding why it does that is appreciated.
AFAIK this is the state of the implementation: The recommended way is to create a PdfDocument or open it from a file, make the changes you need, then save it once.
This is what you do in the implementation that works for you.
Saving the document, opening it, adding more pages, saving it again would also work. This way you would not need a list of all images. But IMHO using the list and creating a new PdfDocument each time you save is the cleanest way.
Unexpected results occur when saving again after further changes. This is a known issue. Feel free to investigate this issue and fix it. Maybe it is just a simple change, maybe it is complicated.
Related
Tried to open a pdf result in blank pages. Retry with same pdf displayed all pages with content.
It happen only once & couldn't reproduce it.
My application work with 3 steps.
Open PDF
Add Barcode Image
Save PDF
Source pdf had 2 pages with text content, output pdf had only stamped pdf without content.
I believe something went wrong in following line because number of pages are correct but blank.
PdfDocument document = PdfReader.Open(filePath, PdfDocumentOpenMode.Modify);
I need find reason of failure but don't have any idea what went wrong at first time. I have already gone through following questions but they have different case.
https://stackoverflow.com/a/52453789/9102192
PDFSharp returning blank pages when adding password
Can anyone help me finding root cause for this incident or any guesses ?
I would try to do something like this:
using (PdfDocument pdfDoc = PdfReader.Open("source", PdfDocumentOpenMode.Modify)){
// Logic to insert image into pdf //
pdfDoc.Save("targetPath")
}
I use PdfSharp to create a PdfDocument object:
private readonly PdfDocument _pdf = new PdfDocument();
Along with the other methods for actually adding the text, setting font styles etc. I then write the pdf file to a temporary location on disk:
var tempPdf = string.Concat(Path.GetTempPath(), Guid.NewGuid().ToString(), ".pdf");
_pdf.Save(tempPdf);
Which I then use in System.Windows.Clipboard class to copy the content to the clipboard:
Clipboard.SetFileDropList(new StringCollection {tempPdf});
When the user pastes the Clipboard content into a Word document for example, the pdf content appears in the document as desired.
The problem I have is that when the user double-clicks on the embedded PDF it launches the PDF in a viewer such as Adobe Reader, also as expected. The (unanticipated) problem I have is that I need to prevent this pop-up from happening given that this content will be inserted into a legal document.
Can any suggest any approaches or strategies for helping me to achieve something like this? To summarise - allowing them to paste [pdf] content stored in the clipboard to a Word document, but without it opening on double-clicking.
The answer was in my question ;)
And credit to Nyerguds for helping me out of my cocoon - I was fixated on using PDF files to copy to the clipboard.
The solution is to replace the usages of PdfSharp for pdf generation with System.Drawing.Graphics / System.Drawing.Bitmap to create jpg images of that which we want to copy.
And once the clipboard contents have been pasted to the Word document, we no longer have that problem of the image being openable on double-clicking.
I use PDF Clown to create PDF files containing text and different shapes. Saving the files brings the desired result. But when I print the pages or render them to bitmaps, only the shapes are visible and the text elements are missing.
I tried already different versions of the library with multiple files, always getting the same result.
Maybe someone can give me a hint on this issue.
EDIT:
This is a simplified form of the source code I use (with same result as described above; see the image at the end):
File file = new File();
Document document = file.Document;
document.PageSize = PageFormat.GetSize(PageFormat.SizeEnum.A4, PageFormat.OrientationEnum.Portrait);
Page page = new Page(document);
document.Pages.Add(page);
PrimitiveComposer composer = new PrimitiveComposer(page);
//draw a rectangle
composer.SetFillColor(DeviceRGBColor.Get(System.Drawing.Color.LightSalmon));
composer.DrawRectangle(new RectangleF(30, 42, 300, 32));
composer.Fill();
//draw some text
composer.SetFillColor(DeviceRGBColor.Get(System.Drawing.Color.Black));
composer.SetFont(new StandardType1Font(document, StandardType1Font.FamilyEnum.Courier, true, false), 32);
composer.ShowText("Hello World!", new PointF(32, 48));
composer.Flush();
//save the file
file.Save(#"..\document.pdf", SerializationModeEnum.Standard);
//and print it
Renderer renderer = new Renderer();
renderer.Print(file.Document, false);
Result of the above code (the printed version was created with virtual printer Adobe PDF; also tested with XPS Document Writer):
(I don't have enough points to add a comment so I put this comment as an answer.) If you look in the source for the RenderingSample class, you will see this comment:
This sample demonstrates how to render a PDF page as a raster image.
Note: rendering is currently in pre-alpha stage; therefore this sample is
nothing but an initial stub (no assumption to work!).
I don't think Stephano Chizzolini got around to finishing it.
There is another NuGet download, PDFClown.Net version 2.0.0, by Matthieu. It has tags for PDF-To-Image, Rasterizer and PDF, but I have not been able to get it to work either. I cannot find documentation for it. Inspection of the properties for the downloaded NuGET assembly shows version 0.1.2.0 instead of 2.0.0.
I'm trying to set a background to a pdf and managed to set it with an image my pdf has a big table so the pages are added automatically not with the Document.NewPage() method so the image background is set only on the first page. This is the code that adds the background:
Image backImg = Image.GetInstance(#"D:\websites\DIS\bugs\130208\A4.png");
backImg.SetAbsolutePosition(0, 0);
backImg.Alignment = Image.UNDERLYING;
var doc = new Document(pageSize);
PdfWriter pdfWriter = PdfWriter.GetInstance(doc, new FileStream(filePath, FileMode.Create));
doc.Open();
doc.Add(backImg);
...
creating a big table
and not using the doc.NewPage() method. Do I have to loop throw every page and add the background image at the end before closing the doc, but how do I put it in the background not on top of the other elements?
Whenever you want to apply something to every page, you should use page events, more specifically PdfPageEvent.onEndPage(), to do it. You can find samples for its usage by keyword Page events > onEndPage --- these samples are taken from iText in Action 2nd Edition. The samples mainly add footers and headers while you want to add background graphics.
Be aware that you shouldn't add content to the Document instance here but instead directly to the PdfWriter, and as you want the image to be under the page content , not above it, you will need to use PdfWriter.getDirectContentUnder() like in the sample Stationery and not PdfWriter.getDirectContent() like in the other samples.
PS: The analogous samples for .Net can be found here.
PPS: The sample ImageDirect.java / ImageDirect.cs shows how to add an image to some direct content which might be the information missing here.
go for
PdfPageEvent.onStartPage()
. In this event, write your code to insert the image (as you are doing it). What it will do is that as soon as a new page is created, it will add the image to it and then the content over it; giving a watermark effect.
I need to display PdfPage of a PDF Document in a WPF form. I am using Docotic.pdf.dll and want to stick to it. The PdfPage.Thumbnail is also giving me null with all PDFs.
Just confirmed from Bit Miracle, this feature has been added in Docotic.Pdf 3.4 (available on their site) and currently it is in beta phase .
Below is the code that will save the image from the Pdf.
using (PdfDocument pdf = new PdfDocument("your_file.pdf"))
{
PdfDrawOptions options = PdfDrawOptions.CreateZoom(150);
options.BackgroundColor = new PdfRgbColor(255, 255, 255); // white background, transparent by default
options.Format = PdfDrawFormat.Jpeg;
pdf.Pages[0].Save("result.jpg", options);
}
There is also Draw and print PDF group of samples that might worth to look into.
As far as I know Docotic.Pdf cannot display PDF files (at least the current version), it can only create them. The PdfPage.Thumbnail refers to the page thumbnail embedded in the PDF file, which usually is missing, this is why the property returns null.