Controlling Image Resolution when coverting a PNG image into a PDF using iTextSharp - vb.net

I have created a PNG image that is 200 DPI, and perfectly sized for a landscape A4 page size. I needed to convert this to a PDF document, so I've used the iTextSharp library with the code below.
This all works, however the image quality has degraded. Any suggestions as to how I might improve this?
Public Sub ConvertPNGtoPDF(ByVal inputFile As String, ByVal outputFile As String)
Using fs As New FileStream(outputFile, FileMode.Create, FileAccess.ReadWrite, FileShare.None)
Dim document As New Document(PageSize.A4.Rotate, 0, 0, 0, 0)
Dim writer As PdfWriter = PdfWriter.GetInstance(document, fs)
document.Open()
Dim cb As PdfContentByte = writer.DirectContent
Using bm As New Bitmap(inputFile)
Dim total As Integer = bm.GetFrameCount(FrameDimension.Page)
For k As Integer = 0 To total - 1
bm.SelectActiveFrame(FrameDimension.Page, k)
Dim img As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(bm, Nothing, False)
img.SetDpi(200, 200)
img.ScalePercent(72.0F / 200.0F * 100)
img.SetAbsolutePosition(0, 0)
cb.AddImage(img)
document.NewPage()
Next
End Using
document.Close()
writer.Close()
End Using
End Sub

This all works, however the image quality has degraded. Any suggestions as to how I might improve this?
Looking at the code in PngImage, it looks like iText doesn't support PNG compression as a PDF-native filter, so it has to be decompressed and recompressed as Something Else. Is this because the PDF spec doesn't support it:
Just checked, sure looks that way.
Best fix? JPEG and JPEG2000 are supported as "native" compression types within PDF (and this is echoed in iText[sharp]). So use JPEG[2k] instead, and run your images through your image conversion library of choice if need be.

Related

How do I make an image not selectable

I have added an image to my iTextSharp PDF document like this:
Public Sub CreatePDFFromBitmap(ByVal uPath As String, ByVal uBitmap As Bitmap)
Dim nFs As System.IO.FileStream = New FileStream(uPath, FileMode.Create)
Dim nDocument As iTextSharp.text.Document
Dim nWriter As iTextSharp.text.pdf.PdfWriter
Dim nCb As iTextSharp.text.pdf.PdfContentByte
Dim nImgFromBitmap As System.Drawing.Image = DirectCast(uBitmap, System.Drawing.Image)
Dim nImg As iTextSharp.text.Image = iTextSharp.text.Image.GetInstance(nImgFromBitmap, Imaging.ImageFormat.Png)
Dim bLandscape As Boolean = (nImg.Width > nImg.Height)
'rotation needs to be set before document is being opened
If bLandscape Then
nDocument = New iTextSharp.text.Document(PageSize.A4.Rotate, 0, 0, 0, 0)
Else
nDocument = New iTextSharp.text.Document(PageSize.A4, 0, 0, 0, 0)
End If
'if an exception is raised here, the following will help: https://stackoverflow.com/questions/15833285/pdfwriter-getinstance-throws-system-nullreferenceexception
nWriter = iTextSharp.text.pdf.PdfWriter.GetInstance(nDocument, nFs)
nDocument.Open()
nCb = nWriter.DirectContent
nImg.ScaleToFit(nDocument.PageSize.Width, nDocument.PageSize.Height) 'raises dpi size :-)))
'X-Y-Koordinatensystem 0,0 startet also unten links, nicht oben-links
nImg.SetAbsolutePosition(0, nDocument.PageSize.Height - nImg.ScaledHeight)
nCb.AddImage(nImg)
nDocument.Close()
nWriter.Close()
nFs.Close()
End Sub
It works fine.
However, when I click the image in the PDF, it gets selected.
This is not what I want.
If I click the image in the PDF, it should not be selected.
This is what it looks like: The image becomes blue:
I want to add editable fields to the PDF, so I need to make the image not selectable, else it would confuse the user.
As Abdel-Rahman Al-Qawasmi mentions in his answer, it is completely up to the PDF viewer which entities it makes selectable and which not. Thus, there is no guaranteed way to get what you want.
Nonetheless, there are ways to put an image into a PDF which dissuade current versions of most PDF viewers from making it selectable. These ways either transform the bitmap image into a non-bitmap entity (e.g. by iterating over the pixels of the bitmap and drawing a little rectangle per pixel using vector graphics) or wrap the bitmap image into something that usually is not selectable.
Let's take the latter approach and wrap the image into a page-size PDF pattern with which we then fill the actual page. You can do that by replacing your
nCb.AddImage(nImg)
by
Dim painter As iTextSharp.text.pdf.PdfPatternPainter = nCb.CreatePattern(nDocument.PageSize.Width, nDocument.PageSize.Height)
painter.AddImage(nImg)
nCb.SetColorFill(New iTextSharp.text.pdf.PatternColor(painter))
nCb.Rectangle(0, 0, nDocument.PageSize.Width, nDocument.PageSize.Height)
nCb.Fill()
(This essentially is the VB/iTextSharp pendant of the Java/iText code from this answer.)
This is a pdf program specifications and not related to asp.net or vb.net programming. you need to have control of the pdf reader settings. Or try to use another format.

PDFsharp bitmap size

I'm using PDFsharp library to transform a control into a PDF file. The problem is that the bitmap image, even if I set height and width and the format is A4, does not fill the view in Adobe Reader.
I also tried to set the parameters manually from DPI but it does not work. The script is:
Dim docum As New PdfDocument()
For i As Integer = 0 To FoglioFattura1.listaPagIndex.Count - 1
Dim memImage = New Bitmap(FoglioFattura1.Width, FoglioFattura1.Height) 'A4Size
FoglioFattura1.DrawToBitmap(memImage, New Rectangle(0, 0, FoglioFattura1.Width, FoglioFattura1.Height))
Dim oPage As New PdfPage()
oPage.Orientation = PageOrientation.Portrait
oPage.Size = PageSize.A4
'oPage.TrimMargins.Left = 30
'oPage.TrimMargins.Top = 50
docum.Pages.Add(oPage)
Dim xgr As XGraphics = XGraphics.FromPdfPage(oPage)
Dim img As XImage = XImage.FromGdiPlusImage(memImage)
xgr.DrawImage(img, 0, 0)
Next
These are the dimensions of the document, I have hidden the content for privacy reasons. I want the document fill the view.
The problem is that you call DrawImage without specifying the destination size of the image in the PDF. Add Width and Height to the DrawImage call and the image will be drawn in the size you specify.
PDFs have no DPI. The size if the PDF page is given in Points - and Points are not pixels.
See also:
https://en.wikipedia.org/wiki/Point_(typography)

Print Bitmap image over multiple pages using PDFSharp, Vb.net

I have a panel which draws a diagram based on user input. Unfortunately the diagrams can get really really big, and when I print them it doesn't entirely fit on a single page without losing readability.
I'm using PDFsharp within VB.net to create the PDF. The current method is the turn the panel in which the diagram is drawn on to a bitmap image, and then place the image in the pdf document.
1 diagram can easily make the panel 1500,3000 in size.
Example of Diagram
Example of Diagram in PDF
Any help is greatly appreciated
Dim pdfdoc As New PdfDocument
Dim page As PdfPage = pdfdoc.AddPage
Dim Bitmap As Bitmap = New Bitmap(pnl_Draw.Width, pnl_Draw.Height)
Dim BXImage As XImage
Dim GFX As XGraphics
Me.pnl_Draw.DrawToBitmap(Bitmap, New Rectangle(0, 0, Bitmap.Width, Height))
Dim pbx As New PictureBox
pbx.Image = Bitmap
BXImage = XImage.FromGdiPlusImage(pbx.Image)
GFX = XGraphics.FromPdfPage(page)
GFX.ScaleTransform(0.82)
GFX.DrawImage(BXImage, 0, 0)
GFX.Dispose()
pdfdoc.Save("G:\test.pdf")
pdfdoc.Close()
Try
Process.Start("G:\test.pdf")
Catch ex As Exception
End Try
Simple solution: in the Adobe Reader Print dialog click on "Poster" to print the image on more than 1 page. Increase the Zoom factor to distribute the poster on as many pages as you need.
You can also increase the page size proportionally to the bitmap size.
BTW: You don't need GFX.ScaleTransform(0.82) if you specify the destination size in the call to GFX.DrawImage.

bitmap image printing using axiohm usbcomm dll

I am using an Axiohm thermal printer for printing POS receipt(USBCOMM.dll for communication). Currently, i am able to print the required details along with an image(.bmp file). Now i need to use a new image instead of the existing image. The new image contains barcode.
When i try printing the new image, all i get is some garbage values. Below is the code that i use. Same code works with old image but not with the new image. Is there any format for image that i need to follow.
Dim filepath As String = AppDomain.CurrentDomain.BaseDirectory + "Resources\PrinterDlls\unnamed.bmp"
Using fs = New FileStream(filepath, FileMode.Open, FileAccess.Read, FileShare.Read)
Dim inpt As Byte() = New Byte(fs.Length) {}
inpt(0) = &H1F
fs.Read(inpt, 1, CInt(fs.Length))
Dim ok As Boolean = Usb_WritePort(True, inpt, inpt.Length, written, IntPtr.Zero)
If Not ok OrElse written <> inpt.Length Then
Throw New Exception("USB write failed")
End If
End Using
Well, this is embarrassing that i am answering my own question. I searched for sometime to resolve and raised the question. Soon after, i came across this video in youtube that explain the bitmap image to create for thermal printing
https://www.youtube.com/watch?v=LdB33eWLjgU
Basically, you need to ensure 3 things while creating the image:
1. 8-bit
2. Greyscale
3. Save as .bmp
And the new image will work like a charm while printing. Also ensure the width is less than the paper width.

How to write string data to tiff file in vb.net

I need to write some data which is string to tiff file. I am doing in the following way
Dim OFile As System.IO.File
Dim OWrite As system.IO.TextWriter
OWrite = OFile.CreateText("Signature.tiff")
OWrite.Write(ControlData)
MessageBox.Show("Signature is recieved and it is saved in Signature.tiff")
ControlData is the string which is to be written to the file.
I am capturing the signature from the user. This function gets the data in string format and i need to create a tiff file using the string data.
When i did in this way, signature.tiff is created but when i opened the image it is giving no preview available.
Can you tell me what is the problem or correct way of doing this?
Thanks a lot.
Dim format As StringFormat = New StringFormat()
Dim MyRect As Rectangle = New Rectangle(0, 0, 400, 400)
Dim MyGraphics As Graphics = Me.CreateGraphics()
Dim MyImg As Image = New Bitmap(MyRect.Width, MyRect.Height, MyGraphics)
Dim imageGraphics As Graphics = Graphics.FromImage(MyImg)
imageGraphics.FillRectangle(Brushes.White, MyRect)
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
imageGraphics.DrawString("Hello Everyone", objFont, Brushes.Black, RectangleF.op_Implicit(MyRect))
MyGraphics.DrawImage(MyImg, MyRect)
MyImg.Save(filename)
Just see this may help you all for converting text string to image.
Thanks.
TIFF files are binary image files. You are writing the string to a text file. Try opening the file in Notepad to check.
You need a way to create an image in memory and save it to TIFF format.
You could use a PictureBox control. Write the string onto the PictureBox then save as a TIFF.