Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Converting PDF to image temporarily for the purpose of reading QR codes

Tags:

c#

.net

pdf

qr-code

I need to be able to read QR codes from PDF files. I am using thoughtworks.QRCode, which accepts an image and returns the data held in the QR code. I have that part working.

However, I need to be able to accept a multipage PDF file and send each page as an image to the QR reader. I then need to save each page of the original PDF as single page PDF's named after the data contained in the QR codes.

What library would you recommend I use for this project? Many that I have seen create permanent images, but I just want temporary ones. Is there something that would easily allow me to do this? Is there perhaps another QR reader that can read pdfs?

Thanks for any advice you might be able to lend!

like image 823
PFranchise Avatar asked Jul 05 '12 16:07

PFranchise


People also ask

Can I convert a PDF to a QR code?

Create your own PDF QR Code in 3 easy steps. Click 'Create QR Code' -> Choose 'PDF QR' type. Upload your PDF or paste the URL to the file. Customize the look and design of the QR Code as you like. Click on Next—and you're done!

What is a dynamic QR code?

Dynamic QR code Dynamic QR codes have a short URL embedded in the code, which can redirect the user to the destination website URL. The destination URL can be changed after the QR code has been generated, while the short URL embedded in the code remains the same.


1 Answers

I used itextsharp and libtiff.NET to extract tiff images from PDF files into memory. Bottom line is itextsharp will give you access to the images, but if they are encoded, you need to do the encoding yourself or use another library, which is where libtiff.NET came in.

The following code was modified based on an answer to a question I asked: PDF Add Text and Flatten

Private Shared Function ExtractImages(ByVal pdf As Byte()) As List(Of Byte())
    Dim images As New List(Of Byte())
    Dim reader As New PdfReader(pdf)

    If (reader IsNot Nothing) Then
        ' Loop through all of the references in the PDF.
        For refIndex = 0 To (reader.XrefSize - 1)
            ' Get the object.
            Dim obj = reader.GetPdfObject(refIndex)

            ' Make sure we have something and that it is a stream.
            If (obj IsNot Nothing) AndAlso obj.IsStream() Then
                ' Cast it to a dictionary object.
                Dim pdfDict = DirectCast(obj, iTextSharp.text.pdf.PdfDictionary)

                ' See if it has a subtype property that is set to /IMAGE.
                If pdfDict.Contains(iTextSharp.text.pdf.PdfName.SUBTYPE) AndAlso (pdfDict.Get(iTextSharp.text.pdf.PdfName.SUBTYPE).ToString() = iTextSharp.text.pdf.PdfName.IMAGE.ToString()) Then
                    ' Grab various properties of the image.
                    Dim filter = pdfDict.Get(iTextSharp.text.pdf.PdfName.FILTER).ToString()
                    Dim width = pdfDict.Get(iTextSharp.text.pdf.PdfName.WIDTH).ToString()
                    Dim height = pdfDict.Get(iTextSharp.text.pdf.PdfName.HEIGHT).ToString()
                    Dim bpp = pdfDict.Get(iTextSharp.text.pdf.PdfName.BITSPERCOMPONENT).ToString()

                    ' Grab the raw bytes of the image
                    Dim bytes = PdfReader.GetStreamBytesRaw(DirectCast(obj, PRStream))

                    ' Images can be encoded in various ways. 
                    ' All of our images are encoded with a single filter.
                    ' If there is a need to decode another filter, it will need to be added.
                    If (filter = iTextSharp.text.pdf.PdfName.CCITTFAXDECODE.ToString()) Then
                        Using ms = New MemoryStream()
                            Using tiff As Tiff = tiff.ClientOpen("memory", "w", ms, New TiffStream())
                                tiff.SetField(TiffTag.IMAGEWIDTH, width)
                                tiff.SetField(TiffTag.IMAGELENGTH, height)
                                tiff.SetField(TiffTag.COMPRESSION, Compression.CCITTFAX4)
                                tiff.SetField(TiffTag.BITSPERSAMPLE, bpp)
                                tiff.SetField(TiffTag.SAMPLESPERPIXEL, 1)

                                tiff.WriteRawStrip(0, bytes, bytes.Length)
                                tiff.Flush()
                                images.Add(ms.ToArray())
                                tiff.Close()
                            End Using
                        End Using
                    Else
                        Throw New NotImplementedException("Decoding this filter has not been implemented")
                    End If
                End If
            End If
        Next
    End If

    Return images
End Function
like image 192
DCNYAM Avatar answered Sep 30 '22 10:09

DCNYAM