为了账号安全,请及时绑定邮箱和手机立即绑定

使用iTextSharp提取图像

使用iTextSharp提取图像

江户川乱折腾 2019-09-26 10:01:50
我一直在成功使用此代码来提取在PDF每页中找到的第一张图像。但是,由于某种未知的原因,它现在无法使用某些新的PDF。我使用了其他工具(Datalogics等),这些工具确实可以用这些新的PDF提取图像。但是,如果可以使用iTextSharp,我不想购买Datalogics或任何工具。谁能告诉我为什么此代码无法在PDF中找到图像?已知:我的PDF每页只有1张图片,没有其他内容。using iTextSharp.text;using iTextSharp.text.pdf;...public static void ExtractImagesFromPDF(string sourcePdf, string outputPath){     // NOTE:  This will only get the first image it finds per page.     PdfReader pdf = new PdfReader(sourcePdf);     RandomAccessFileOrArray raf = new iTextSharp.text.pdf.RandomAccessFileOrArray(sourcePdf);     try     {         for (int pageNumber = 1; pageNumber <= pdf.NumberOfPages; pageNumber++)         {             PdfDictionary pg = pdf.GetPageN(pageNumber);             PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));             PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));             if (xobj != null)             {                 foreach (PdfName name in xobj.Keys)                 {                     PdfObject obj = xobj.Get(name);                     if (obj.IsIndirect())                     {                         PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);                         PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));                         if (PdfName.IMAGE.Equals(type))                         {                             int XrefIndex = Convert.ToInt32(((PRIndirectReference)obj).Number.ToString(System.Globalization.CultureInfo.InvariantCulture));                             PdfObject pdfObj = pdf.GetPdfObject(XrefIndex);                             PdfStream pdfStrem = (PdfStream)pdfObj;                             byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStrem);                             if ((bytes != null))                             {                                          }                             }                         }                     }                 }             }         }
查看完整描述

3 回答

?
阿晨1998

TA贡献2037条经验 获得超6个赞

这是一个更简单的解决方案:

iTextSharp.text.pdf.parser.PdfImageObject pdfImage = 
                            new iTextSharp.text.pdf.parser.PdfImageObject(imgPRStream);
                        System.Drawing.Image img = pdfImage.GetDrawingImage();


查看完整回答
反对 回复 2019-09-26
?
犯罪嫌疑人X

TA贡献2080条经验 获得超4个赞

以下代码合并了Dave和R Ubben的所有想法,并返回了所有图像的完整列表,还处理了多个位深度。我不得不将其转换为我正在从事的项目的VB,对此感到抱歉...

Private Sub getAllImages(ByVal dict As pdf.PdfDictionary, ByVal images As List(Of Byte()), ByVal doc As pdf.PdfReader)
    Dim res As pdf.PdfDictionary = CType(pdf.PdfReader.GetPdfObject(dict.Get(pdf.PdfName.RESOURCES)), pdf.PdfDictionary)
    Dim xobj As pdf.PdfDictionary = CType(pdf.PdfReader.GetPdfObject(res.Get(pdf.PdfName.XOBJECT)), pdf.PdfDictionary)

    If xobj IsNot Nothing Then
        For Each name As pdf.PdfName In xobj.Keys
            Dim obj As pdf.PdfObject = xobj.Get(name)
            If (obj.IsIndirect) Then
                Dim tg As pdf.PdfDictionary = CType(pdf.PdfReader.GetPdfObject(obj), pdf.PdfDictionary)
                Dim subtype As pdf.PdfName = CType(pdf.PdfReader.GetPdfObject(tg.Get(pdf.PdfName.SUBTYPE)), pdf.PdfName)
                If pdf.PdfName.IMAGE.Equals(subtype) Then
                    Dim xrefIdx As Integer = CType(obj, pdf.PRIndirectReference).Number
                    Dim pdfObj As pdf.PdfObject = doc.GetPdfObject(xrefIdx)
                    Dim str As pdf.PdfStream = CType(pdfObj, pdf.PdfStream)
                    Dim bytes As Byte() = pdf.PdfReader.GetStreamBytesRaw(CType(str, pdf.PRStream))

                    Dim filter As String = tg.Get(pdf.PdfName.FILTER).ToString
                    Dim width As String = tg.Get(pdf.PdfName.WIDTH).ToString
                    Dim height As String = tg.Get(pdf.PdfName.HEIGHT).ToString
                    Dim bpp As String = tg.Get(pdf.PdfName.BITSPERCOMPONENT).ToString

                    If filter = "/FlateDecode" Then
                        bytes = pdf.PdfReader.FlateDecode(bytes, True)
                        Dim pixelFormat As System.Drawing.Imaging.PixelFormat
                        Select Case Integer.Parse(bpp)
                            Case 1
                                pixelFormat = Drawing.Imaging.PixelFormat.Format1bppIndexed
                            Case 24
                                pixelFormat = Drawing.Imaging.PixelFormat.Format24bppRgb
                            Case Else
                                Throw New Exception("Unknown pixel format " + bpp)
                        End Select
                        Dim bmp As New System.Drawing.Bitmap(Int32.Parse(width), Int32.Parse(height), pixelFormat)
                        Dim bmd As System.Drawing.Imaging.BitmapData = bmp.LockBits(New System.Drawing.Rectangle(0, 0, Int32.Parse(width), Int32.Parse(height)), System.Drawing.Imaging.ImageLockMode.WriteOnly, pixelFormat)
                        Marshal.Copy(bytes, 0, bmd.Scan0, bytes.Length)
                        bmp.UnlockBits(bmd)
                        Using ms As New MemoryStream
                            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png)
                            bytes = ms.GetBuffer
                        End Using
                    End If
                    images.Add(bytes)
                ElseIf pdf.PdfName.FORM.Equals(subtype) Or pdf.PdfName.GROUP.Equals(subtype) Then
                    getAllImages(tg, images, doc)
                End If
            End If
        Next
    End IfEnd Sub


查看完整回答
反对 回复 2019-09-26
  • 3 回答
  • 0 关注
  • 1180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信