Extraction D'image à partir de PDF avec / ccittfaxdecode filter

j'ai un pdf qui a été généré à partir d'un logiciel de numérisation. Le pdf A 1 image TIFF par page. Je veux extraire l'image TIFF de chaque page.

j'utilise iTextSharp et j'ai réussi à trouver les images et je peux récupérer les octets bruts à partir du PdfReader.GetStreamBytesRaw méthode. Le problème est, comme beaucoup avant moi ont découvert, iTextSharp ne contient pas un PdfReader.CCITTFaxDecode méthode.

Qu'est-ce que je sais d'autre? Même sans iTextSharp je peux ouvrir le pdf dans notepad et trouver les flux /Filter /CCITTFaxDecode et je sais de l' /DecodeParams qu'il utilise CCITTFaxDecode groupe 4.

Est-ce que quelqu'un sait comment je peux obtenir les images de filtre CCITTFaxDecode de mon pdf?

Cheers, Kahu

14
demandé sur Bobrovsky 2010-04-15 03:33:45

5 réponses

en fait, la réponse de vbcrlfuser m'a aidé, mais le code n'était pas tout à fait correct pour la version actuelle de BitMiracle.LibTiff.NET comme je pouvais le télécharger. Dans la version actuelle, le code équivalent ressemble à ceci:

using iTextSharp.text.pdf;
using BitMiracle.LibTiff.Classic;

...
      Tiff tiff = Tiff.Open("C:\test.tif", "w");
      tiff.SetField(TiffTag.IMAGEWIDTH, UInt32.Parse(pd.Get(PdfName.WIDTH).ToString()));
      tiff.SetField(TiffTag.IMAGELENGTH, UInt32.Parse(pd.Get(PdfName.HEIGHT).ToString()));
      tiff.SetField(TiffTag.COMPRESSION, Compression.CCITTFAX4);
      tiff.SetField(TiffTag.BITSPERSAMPLE, UInt32.Parse(pd.Get(PdfName.BITSPERCOMPONENT).ToString()));
      tiff.SetField(TiffTag.SAMPLESPERPIXEL, 1);
      tiff.WriteRawStrip(0, raw, raw.Length);
      tiff.Close();

en utilisant le code ci-dessus, je enfin obtenu un permis valide de fichier Tiff en C:\test.tif. Merci, vbcrlfuser!

13
répondu Berend Engelbrecht 2010-08-29 08:09:12

Cette bibliothèque... http://www.bitmiracle.com/libtiff/ et cet exemple ci-dessous devraient vous permettre de 99% de la sorte, il

string filter = pd.Get(PdfName.FILTER).ToString();
string width = pd.Get(PdfName.WIDTH).ToString();
string height = pd.Get(PdfName.HEIGHT).ToString();
string bpp = pd.Get(PdfName.BITSPERCOMPONENT).ToString();

switch (filter)
{
   case "/CCITTFaxDecode":

      byte[] data = PdfReader.GetStreamBytesRaw((PRStream)pdfStream);
      int tiff = TIFFOpen("example.tif", "w");
      TIFFSetField(tiff, (uint)BitMiracle.LibTiff.Classic.TiffTag.IMAGEWIDTH,(uint)Int32.Parse(width));
      TIFFSetField(tiff, (uint)BitMiracle.LibTiff.Classic.TiffTag.IMAGEHEIGHT, (uint)Int32.Parse(height));
      TIFFSetField(tiff, (uint)BitMiarcle.LibTiff.Classic.TiffTag.COMPRESSION, (uint)BitMiracle.Libtiff.Classic.Compression.CCITTFAX4);
      TIFFSetField(tiff, (uint)BitMiracle.LibTiff.Classic.TiffTag.BITSPERSAMPLE, (uint)Int32.Parse(bpp));
      TIFFSetField(tiff, (uint)BitMiarcle.Libtiff.Classic.TiffTag.SAMPLESPERPIXEL,1 );

      IntPtr pointer = Marshal.AllocHGlobal(data.length);
      Marshal.copy(data, 0, pointer, data.length);
      TIFFWriteRawStrip(tiff, 0, pointer, data.length);
      TIFFClose(tiff);

      break;




      break;

}
6
répondu vbcrlfuser 2010-05-24 15:44:28

Voici l'implémentation de python:

import PyPDF2
import struct

"""
Links:
PDF format: http://www.adobe.com/content/dam/Adobe/en/devnet/acrobat/pdfs/pdf_reference_1-7.pdf
CCITT Group 4: https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-T.6-198811-I!!PDF-E&type=items
Extract images from pdf: http://stackoverflow.com/questions/2693820/extract-images-from-pdf-without-resampling-in-python
Extract images coded with CCITTFaxDecode in .net: http://stackoverflow.com/questions/2641770/extracting-image-from-pdf-with-ccittfaxdecode-filter
TIFF format and tags: http://www.awaresystems.be/imaging/tiff/faq.html
"""


def tiff_header_for_CCITT(width, height, img_size, CCITT_group=4):
    tiff_header_struct = '<' + '2s' + 'h' + 'l' + 'h' + 'hhll' * 8 + 'h'
    return struct.pack(tiff_header_struct,
                       b'II',  # Byte order indication: Little indian
                       42,  # Version number (always 42)
                       8,  # Offset to first IFD
                       8,  # Number of tags in IFD
                       256, 4, 1, width,  # ImageWidth, LONG, 1, width
                       257, 4, 1, height,  # ImageLength, LONG, 1, lenght
                       258, 3, 1, 1,  # BitsPerSample, SHORT, 1, 1
                       259, 3, 1, CCITT_group,  # Compression, SHORT, 1, 4 = CCITT Group 4 fax encoding
                       262, 3, 1, 0,  # Threshholding, SHORT, 1, 0 = WhiteIsZero
                       273, 4, 1, struct.calcsize(tiff_header_struct),  # StripOffsets, LONG, 1, len of header
                       278, 4, 1, height,  # RowsPerStrip, LONG, 1, lenght
                       279, 4, 1, img_size,  # StripByteCounts, LONG, 1, size of image
                       0  # last IFD
                       )

pdf_filename = 'scan.pdf'
pdf_file = open(pdf_filename, 'rb')
cond_scan_reader = PyPDF2.PdfFileReader(pdf_file)
for i in range(0, cond_scan_reader.getNumPages()):
    page = cond_scan_reader.getPage(i)
    xObject = page['/Resources']['/XObject'].getObject()
    for obj in xObject:
        if xObject[obj]['/Subtype'] == '/Image':
            """
            The  CCITTFaxDecode filter decodes image data that has been encoded using
            either Group 3 or Group 4 CCITT facsimile (fax) encoding. CCITT encoding is
            designed to achieve efficient compression of monochrome (1 bit per pixel) image
            data at relatively low resolutions, and so is useful only for bitmap image data, not
            for color images, grayscale images, or general data.

            K < 0 --- Pure two-dimensional encoding (Group 4)
            K = 0 --- Pure one-dimensional encoding (Group 3, 1-D)
            K > 0 --- Mixed one- and two-dimensional encoding (Group 3, 2-D)
            """
            if xObject[obj]['/Filter'] == '/CCITTFaxDecode':
                if xObject[obj]['/DecodeParms']['/K'] == -1:
                    CCITT_group = 4
                else:
                    CCITT_group = 3
                width = xObject[obj]['/Width']
                height = xObject[obj]['/Height']
                data = xObject[obj]._data  # sorry, getData() does not work for CCITTFaxDecode
                img_size = len(data)
                tiff_header = tiff_header_for_CCITT(width, height, img_size, CCITT_group)
                img_name = obj[1:] + '.tiff'
                with open(img_name, 'wb') as img_file:
                    img_file.write(tiff_header + data)
                #
                # import io
                # from PIL import Image
                # im = Image.open(io.BytesIO(tiff_header + data))
pdf_file.close()
5
répondu Sergey Shashkov 2016-08-04 07:40:31

peut-être Pouvez-vous essayer de décompresser le pdf avec pdftk? La syntaxe est

pdftk infile.pdf output uncompressed.pdf uncompress

Je n'ai pas de pdf codé CCITTFax ici donc je ne peux pas le tester.

0
répondu topskip 2010-04-21 15:55:24

Il a été écrit. extension pour ceci .C'est si simple!--4-->

PdfDictionary item;
if (item.IsImage()) {
  Image image = item.ToImage();
}
-1
répondu Adem Aygun 2017-12-19 06:50:03