Footer and Watermark added by iTextSharp not appearing in Edge but OK in Chrome - pdf

I create pdfs using iTextSharp and add a footnote and watermark to these using a PdfStamper. This has been working fine. Recently the footers and watermarks have not been appearing when the pdfs are viewed in MS Edge. However, if I view the same pdf in Chrome the footers and watermarks appear correctly.
I store the pdfs in blob storage in Azure.
I have recently changed iTextSharp version from V4.1.2.0 to V5.5.13.
The code for adding watermarks and footers is as follows:
Dim byteArray As Byte()
Using stream As MemoryStream = New MemoryStream
reportBlockBlob.DownloadToStream(stream)
reader = New PdfReader(CType(stream.ToArray(), Byte()))
If reader IsNot Nothing Then
Using stamper As PdfStamper = New PdfStamper(reader, stream)
Dim PageCount As Integer = reader.NumberOfPages
If bReportInvalid Then
For i As Integer = 1 To PageCount
StampWaterMark(stamper, i, "INVALID", fontReport60, 35, New text.BaseColor(70, 70, 255), reader.GetPageSizeWithRotation(i))
Next
ElseIf Not UserRoles.Contains(WaspWAVB.con.csUserRoleCertificateSignOff) Then
For i As Integer = 1 To PageCount
StampWaterMark(stamper, i, "DRAFT", fontReport60, 35, New text.BaseColor(70, 70, 255), reader.GetPageSizeWithRotation(i))
Next
End If
If bAddFooter Then
Dim sRepUCN As String = "UCN"
Dim sCopyright As String = "Copyright"
Dim yPos As Integer = 12
Dim xLeftPos As Integer = 36
Dim xMidPos As Single = 297.5
Dim xRightPos As Integer = 559
For i As Integer = 3 To PageCount - iAppendixCount
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_LEFT, New text.Phrase(sRepUCN, fontMedium), xLeftPos, yPos, 0)
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_CENTER, New text.Phrase(sCopyright, fontMedium), xMidPos, yPos, 0)
Dim rttnPg As Integer = reader.GetPageRotation(i)
If rttnPg <> 0 Then
xRightPos = 806
End If
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_RIGHT, New text.Phrase(String.Format(WaspWAVB.con.csPageXofY, i - 2, PageCount - 2 - iAppendixCount), fontMedium), xRightPos, yPos, 0)
Next
End If
End Using
byteArray = stream.ToArray()
End If
End Using
reportBlockBlob.Properties.ContentType = "application/pdf"
reportBlockBlob.UploadFromByteArray(byteArray, 0, byteArray.Length)
Public Shared Sub StampWaterMark(ByRef stamper As PdfStamper,
ByVal i As Integer,
ByVal watermark As String,
ByVal font As text.Font,
ByVal angle As Single,
ByVal color As text.BaseColor,
ByVal realPageSize As text.Rectangle,
Optional ByVal rect As text.Rectangle = Nothing)
Dim gstate = New PdfGState()
gstate.FillOpacity = 0.1F
gstate.StrokeOpacity = 0.3F
stamper.GetOverContent(i).SaveState()
stamper.GetOverContent(i).SetGState(gstate)
stamper.GetOverContent(i).SetColorFill(color)
stamper.GetOverContent(i).BeginText()
Dim ps = If(rect, realPageSize)
Dim x = (ps.Right + ps.Left) / 2
Dim y = (ps.Bottom + ps.Top) / 2
ColumnText.ShowTextAligned(stamper.GetOverContent(i), text.Element.ALIGN_CENTER, New text.Phrase(watermark, font), x, y, angle)
End Sub
I have tried re-arranging the order in which the footer and watermark are applied and commenting out either the addition of watermark or footer. None of this helps.
I use the code to add a footer elsewhere in the code and this works. Where it works, the footer is applied to an individual page. Where it doesn't work I have just collected together pages stored in separate blobs and amalgamated them into one memorystream. The footer and watermark are applied to this.
What is mystifying is that the pdf works fine in Chrome but not in Edge. This works either way round - i.e. if I create it in Chrome and view it in Edge, the footers disappear and if I create it in Edge and view it in Chrome, the footers appear.
Has anyone else seen this problem and knows how to solve it?

Related

VB.NET get any file thumbnail in picturebox as an image image programmatically [duplicate]

This question already has answers here:
C# get thumbnail from file via windows api
(5 answers)
Closed 1 year ago.
I am struggling to find a way on how to get any file thumbnail into my userforms picturebox (The image visible in windows explorer) using visual basic.
I have only found how to do that for image files
Dim image As Image = New Bitmap(file) 'File is a full path to the file
'Resize and preserve aspect ratio
Dim Ratio As Double = CDbl(image.Width / image.Height)
Dim H As Integer = 150
Dim W As Integer = CInt(H / Ratio)
'Set image
.Image = image.GetThumbnailImage(H, W, callback, New IntPtr())
But it doesn't work for any other type of files.
Could someone, please,help me with this code?
Try the following which is adapted from C# get thumbnail from file via windows api
Download/install NuGet package Microsoft-WindowsAPICodePack-Shell
Imports Microsoft.WindowsAPICodePack.Shell
Imports System.IO
...
Private Function GetThumbnailBytes(filename As String, desiredHeight As Integer) As Byte()
Dim thumbnailBytes As Byte()
Using sfile As ShellFile = ShellFile.FromFilePath(filename)
Dim thumbBmp As Bitmap = sfile.Thumbnail.ExtraLargeBitmap
'compute new width
Dim Ratio As Double = CDbl(thumbBmp.Width / thumbBmp.Height)
Dim height As Integer = desiredHeight
Dim width As Integer = CInt(height / Ratio)
'resize
Using resizedBmp As Bitmap = New Bitmap(thumbBmp, width, height)
Using ms As MemoryStream = New MemoryStream()
resizedBmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
thumbnailBytes = ms.ToArray()
End Using
End Using
End Using
Return thumbnailBytes
End Function
Private Sub btnRun_Click(sender As Object, e As EventArgs) Handles btnRun.Click
Using ofd As OpenFileDialog = New OpenFileDialog()
If ofd.ShowDialog() = DialogResult.OK Then
Dim thumbnailBytes = GetThumbnailBytes(ofd.FileName, 60)
Dim thumbnail = GetThumbnail(ofd.FileName, 60)
Using ms As MemoryStream = New MemoryStream(thumbnailBytes)
PictureBox1.Image = Image.FromStream(ms)
PictureBox1.SizeMode = PictureBoxSizeMode.StretchImage
End Using
End If
End Using
End Sub
Resources
C# get thumbnail from file via windows api

Out of memory exception when merging multiple pdf

I have to merge multiple pdf's into one pdf. I'm using iTextSHarp 5.5.10.0 to accomplish this, and it work fine when I merge small files( 2 or more, with 20 pages each), and even work when I try to merge 2 files, one with 3000 pages and the second with 1300 pages, but when I try to merge 3 pdf's with 3000 pages each, I get an out of memory exception.
I don't know how to solve this.
I'm using fileStream and not memoryStream.
I took the code from the answer to this question:
VB.Net Merge multiple pdfs into one and export
Public Function MergePdfFiles(ByVal pdfFiles() As String, ByVal outputPath As String) As Boolean
Dim result As Boolean = False
Dim pdfCount As Integer = 0 'total input pdf file count
Dim f As Integer = 0 'pointer to current input pdf file
Dim fileName As String
Dim reader As iTextSharp.text.pdf.PdfReader = Nothing
Dim pageCount As Integer = 0
Dim pdfDoc As iTextSharp.text.Document = Nothing 'the output pdf document
Dim writer As PdfWriter = Nothing
Dim cb As PdfContentByte = Nothing
Dim page As PdfImportedPage = Nothing
Dim rotation As Integer = 0
Try
pdfCount = pdfFiles.Length
If pdfCount > 1 Then
'Open the 1st item in the array PDFFiles
fileName = pdfFiles(f)
reader = New iTextSharp.text.pdf.PdfReader(fileName)
'Get page count
pageCount = reader.NumberOfPages
pdfDoc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1), 18, 18, 18, 18)
writer = PdfWriter.GetInstance(pdfDoc, New FileStream(outputPath, FileMode.OpenOrCreate))
With pdfDoc
.Open()
End With
'Instantiate a PdfContentByte object
cb = writer.DirectContent
'Now loop thru the input pdfs
While f < pdfCount
'Declare a page counter variable
Dim i As Integer = 0
'Loop thru the current input pdf's pages starting at page 1
While i < pageCount
i += 1
'Get the input page size
pdfDoc.SetPageSize(reader.GetPageSizeWithRotation(i))
'Create a new page on the output document
pdfDoc.NewPage()
'If it is the 1st page, we add bookmarks to the page
'Now we get the imported page
page = writer.GetImportedPage(reader, i)
'Read the imported page's rotation
rotation = reader.GetPageRotation(i)
'Then add the imported page to the PdfContentByte object as a template based on the page's rotation
If rotation = 90 Then
cb.AddTemplate(page, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(i).Height)
ElseIf rotation = 270 Then
cb.AddTemplate(page, 0, 1.0F, -1.0F, 0, reader.GetPageSizeWithRotation(i).Width + 60, -30)
Else
cb.AddTemplate(page, 1.0F, 0, 0, 1.0F, 0, 0)
End If
End While
'Increment f and read the next input pdf file
f += 1
If f < pdfCount Then
fileName = pdfFiles(f)
reader = New iTextSharp.text.pdf.PdfReader(fileName)
pageCount = reader.NumberOfPages
End If
End While
'When all done, we close the document so that the pdfwriter object can write it to the output file
pdfDoc.Close()
result = True
End If
Catch ex As Exception
Return False
End Try
Return result
End Function
I get the Exception from this line, in the end of the while, when trying to read the second file:
reader = New iTextSharp.text.pdf.PdfReader(fileName)
How can I solve this?

Resizing existing pdfpage not top centered

All,
I am trying to resize an existing PDF file but the result is not centered, what am I doing wrong? I am using PDFsharp, please see below code:
Private Sub ResizePDF(sourcePDF As String, outPDF As String)
Dim form As XPdfForm = XPdfForm.FromFile(sourcePDF)
Dim doc2 As New PdfSharp.Pdf.PdfDocument()
doc2.Options.CompressContentStreams = True
doc2.Options.ColorMode = PdfSharp.Pdf.PdfColorMode.Rgb
For pagenumber As Integer = 1 To (form.PageCount + 1) - 1
Dim page As PdfSharp.Pdf.PdfPage = doc2.Pages.Add()
form.PageNumber = pagenumber
page.Width = form.PixelWidth + 15.36
page.Height = form.PixelHeight + 40.32
Dim graph As XGraphics = XGraphics.FromPdfPage(page)
Dim rect As New XRect(0, 0, page.Width, page.Height)
graph.DrawImage(form, rect)
Next
If IO.Directory.Exists(IO.Path.GetDirectoryName(outPDF)) = False Then IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(outPDF))
doc2.Save(outPDF)
End Sub
Input file: https://www.dropbox.com/s/po87x8c44r90py2/HFD_20151007_0_001_061.pdf?dl=0
Ouput File: https://www.dropbox.com/s/pt5pcyfayri6ory/HFD_20151007_0_001_061_output.pdf?dl=0
We have a workaround for you: Instead of calling graph.DrawImage(form, rect) please call
graph.DrawImage(form, rect.X - form.Page.MediaBox.X1, rect.Y + form.Page.MediaBox.Y1, rect.Width, rect.Height).
I'm not sure if this is valid VB.NET, but it works in C# and should work for VB.NET with little or no changes.
This is a workaround needed for PDFsharp 1.50 beta 2 and all earlier versions.
When switching to PDFsharp 1.50 beta 3 or a later version (not yet available), you will have to use the initial code graph.DrawImage(form, rect) again.

ReportViewer.LocalReport.Render("PDF")

I am using Report Viewer for WinForms. The problem i am having is this: I have a form that contains a form which is used to view a local report which work fine, but when I try to render the same report as a PDF, it is cut-off, but in report viewer the same report renders a report on one page. When I render to PDF it cuts it off and the part of the report that was cut-off renders on a 2nd page. So in other words, part of the same report is on page 1, and 2nd half is on 2nd page in the PDF?
Code:
Private Function GetPDfReport() As String
Dim parameters = Me.GetReportParms()
Dim query = Me.GetReportQuery()
Dim rView As Microsoft.Reporting.WinForms.ReportViewer = New Microsoft.Reporting.WinForms.ReportViewer
rView.Dock = DockStyle.Fill
rView.SetDisplayMode(DisplayMode.PrintLayout)
Dim pnl As New Panel()
pnl.Name = "pnlMain"
pnl.Location = New System.Drawing.Point(0, 25)
pnl.Size = New System.Drawing.Size(734, 478)
pnl.Controls.Add(rView)
Dim dbReader As New dbReader()
Dim ds As DataSet = dbReader.DataSet(query)
Dim rds As Microsoft.Reporting.WinForms.ReportDataSource = New Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", ds.Tables(0))
rView.ProcessingMode = Microsoft.Reporting.WinForms.ProcessingMode.Local
rView.LocalReport.DataSources.Add(rds)
rView.LocalReport.ReportEmbeddedResource = "EasyDose.rptIncident.rdlc"
If Not IsNothing(parameters) Then
Dim Bound0 As Integer = parameters.GetUpperBound(0)
Dim Bound1 As Integer = parameters.GetUpperBound(1)
For index = 0 To Bound0
Dim rParameter As New ReportParameter(parameters(index, 0), parameters(index, 1))
rView.LocalReport.SetParameters(rParameter)
Next
End If
Dim ps As PageSettings = rView.GetPageSettings
ps.Margins.Top = 0 ' 10mm approx
ps.Margins.Right = 0
ps.Margins.Bottom = 0
ps.Margins.Left = 0
ps.Landscape = False
'ps.PaperSize = New PaperSize("LetterExtra", (9.275 * 100), (12 * 100)) ' Letter paper (8.5 in. by 11 in.) ' Letter extra paper (9.275 in. by 12 in.)
ps.PaperSize = New PaperSize("A4", (8.27 * 100), (11.69 * 100))
rView.RefreshReport()
Dim exePath As String = System.IO.Path.GetDirectoryName(Application.ExecutablePath)
Dim dir As New DirectoryInfo(System.IO.Path.Combine(exePath, "tmpDir"))
Dim file As New FileInfo(System.IO.Path.Combine( _
dir.FullName, String.Format("Patient_Details_{0:yyyyMMdd_hhmmss}.pdf", DateTime.Now)))
If Not dir.Exists Then
dir.Create()
End If
Dim bytes As Byte() = rView.LocalReport.Render("PDF")
Using fs As New System.IO.FileStream(file.FullName, System.IO.FileMode.Create)
fs.Write(bytes, 0, bytes.Length)
fs.Close()
End Using
Return file.FullName
End Function
are you seeing the local report in the embedded ReportViewer using the "Print Layout" option activated? That should show exactly the same output as your printed result.
If you have problems in the PDF is probably caused by the design of the report itself. Check the font, the page size and orientation, the margins, the page breaks.
uisng System.IO;
byte[] rep = reportViewer1.LocalReport.Render("pdf", deviceInfo: "");
// if a certificate warning appears just ignore and re-run
File.WriteAllBytes(filepath+filename+".pdf",rep);

Create Table of Contents using iTextSharp

I'm working on some code that I can't make it work.
I have a program that takes multiple pdf's and merges them into one file. Now I need to create a table of contents on the first page. You can see examples of the documents below.
I would like to outsource this to someone who is an expert with iTextSharp. I don't think this will take more than an hour or two the most.
The requirements are:
The toc will be based of the bookmarks.
The toc text will be linked to the proper page so the user can click on the text to go to the page.
The existing bookmarks in sampe1.pdf must remain.
The page numbers are already calculated, so do don't have to worry about that.
The working code must be part of the VB.Net project files I give you. I've tried several snippets without luck, I would like it to just work without me having to adapt the code.
The file I generate looks like this: http://gamepacks.org/sample1.pdf
The file with toc should look like this (layout, not the font style): http://gamepacks.org/sample2.pdf
I would appreciate anyone who can help me out.
The code I used to generate sample1.pdf looks like this to give you an idea what you need to work with.
Public Sub MergePdfFiles(ByVal docList As List(Of Portal.DocumentRow), ByVal outputPath As String)
'
' http://www.vbforums.com/showthread.php?475920-Merge-Pdf-Files-and-Add-Bookmarks-to-It-(Using-iTextSharp)
'
If docList.Count = 0 Then Exit Sub
Dim tmpFile As String = "c:\STEP_1_Working.pdf"
Dim OutlineList As List(Of PdfOutline) = New List(Of PdfOutline)
Dim FirstPageIndex As Integer = 1 ' Tracks which page to link the bookmark
Dim result As Boolean = False
Dim pdfCount As Integer = 0 'total input pdf file count
Dim fileName As String = String.Empty 'current input pdf filename
Dim reader As iTextSharp.text.pdf.PdfReader = Nothing
Dim pageCount As Integer = 0 'current input pdf page count
Dim doc As iTextSharp.text.Document = Nothing 'the output pdf document
Dim writer As PdfWriter = Nothing
Dim cb As PdfContentByte = Nothing
'Declare a variable to hold the imported pages
Dim page As PdfImportedPage = Nothing
Dim rotation As Integer = 0
'Now loop thru the input pdfs
For Each row As Portal.DocumentRow In docList
reader = New iTextSharp.text.pdf.PdfReader(row.FilePath)
' Is this the first pdf file
If (row.Name = docList(0).Name) Then
doc = New iTextSharp.text.Document(reader.GetPageSizeWithRotation(1), 18, 18, 18, 18)
writer = PdfWriter.GetInstance(doc, New IO.FileStream(tmpFile, IO.FileMode.Create))
' Always show the bookmarks
writer.ViewerPreferences = PdfWriter.PageModeUseOutlines
'Set metadata and open the document
With doc
.AddAuthor("Sample Title")
.AddCreationDate()
.Open()
End With
'Instantiate a PdfContentByte object
cb = writer.DirectContentUnder
End If
For i As Integer = 1 To reader.NumberOfPages
'Get the input page size
doc.SetPageSize(reader.GetPageSizeWithRotation(i))
'Create a new page on the output document
doc.NewPage()
'If it is the 1st page, we add bookmarks to the page
If i = 1 Then
If row.Parent = "" Then
Dim oline As PdfOutline = New PdfOutline(cb.RootOutline, PdfAction.GotoLocalPage(FirstPageIndex, New PdfDestination(FirstPageIndex), writer), row.Name)
Else
Dim parent As PdfOutline = Nothing
For Each tmp As PdfOutline In cb.RootOutline.Kids
If tmp.Title = row.Parent Then
parent = tmp
End If
Next
' Create new group outline
If parent Is Nothing Then
parent = New PdfOutline(cb.RootOutline, PdfAction.GotoLocalPage(FirstPageIndex, New PdfDestination(FirstPageIndex), writer), row.Parent)
End If
' Add to new parent
Dim oline As PdfOutline = New PdfOutline(parent, PdfAction.GotoLocalPage(FirstPageIndex, New PdfDestination(FirstPageIndex), writer), row.Name)
OutlineList.Add(oline)
End If
FirstPageIndex += reader.NumberOfPages
End If
'Now we get the imported page
page = writer.GetImportedPage(reader, i)
'Read the imported page's rotation
rotation = reader.GetPageRotation(i)
'Then add the imported page to the PdfContentByte object as a template based on the page's rotation
If rotation = 90 Then
cb.AddTemplate(page, 0, -1.0F, 1.0F, 0, 0, reader.GetPageSizeWithRotation(i).Height)
ElseIf rotation = 270 Then
cb.AddTemplate(page, 0, 1.0F, -1.0F, 0, reader.GetPageSizeWithRotation(i).Width + 60, -30)
Else
cb.AddTemplate(page, 1.0F, 0, 0, 1.0F, 0, 0)
End If
Next
Next
doc.Close()
End Sub