2012-07-05 46 views
5

Necesito poder leer códigos QR de archivos PDF. Estoy usando thoughtworks.QRCode, que acepta una imagen y devuelve los datos contenidos en el código QR. Tengo esa parte trabajando.Convertir PDF a imagen temporalmente con el propósito de leer códigos QR

Sin embargo, necesito poder aceptar un archivo PDF multipágina y enviar cada página como una imagen al lector QR. Luego, debo guardar cada página del PDF original como PDF de una sola página con el nombre de los datos contenidos en los códigos QR.

¿Qué biblioteca recomendaría que use para este proyecto? Muchos de los que he visto crean imágenes permanentes, pero solo quiero temporales. ¿Hay algo que me permita fácilmente hacer esto? ¿Hay quizás otro lector QR que pueda leer archivos PDF?

¡Gracias por cualquier consejo que pueda prestar!

Respuesta

5

Utilicé itextsharp y libtiff.NET para extraer imágenes tiff de archivos PDF en la memoria. La línea de fondo es itextsharp le dará acceso a las imágenes, pero si están codificadas, necesita hacer la codificación usted mismo o usar otra biblioteca, que es donde libtiff.NET entró.

El siguiente código se modificó en función de una respuesta a una pregunta que hice: 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