在.net中提取图像代码,我可以';我不能让它工作
我想简单地从pdf中提取所有图像。我发现一些代码看起来正是我需要的在.net中提取图像代码,我可以';我不能让它工作,.net,itextsharp,.net,Itextsharp,我想简单地从pdf中提取所有图像。我发现一些代码看起来正是我需要的 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)),
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 If End Sub
现在我的问题很简单,我该怎么称呼它呢,我不知道该将dict变量设置为什么或图像列表
所以在essance中,如果我在C:\temp\test.PDF中有一个包含图像的PDF文件,我该如何称呼它
Dim x As New FileStream("C:\image\test.pdf", FileMode.Open)
Dim reader As New iTextSharp.text.pdf.PdfReader(x)
getAllImages(?????, ?????? ,reader)
如果您不了解PDF和/或iTextSharp的内部结构,那么此人编写此方法的方式可能看起来很奇怪。该方法有三个参数,第一个参数是
PdfDictionary
,您可以通过在每个页面上调用GetPageN(Integer)
来获取该参数。第二个是一个通用列表,您需要在调用它之前自己初始化它。此方法旨在对PDF中的每个页面进行循环调用,每次调用都会将图像附加到此列表中。您已经了解的最后一个参数
下面是调用此方法的代码:
''//Source file to read images from
Dim InputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "FileWithImages.pdf")
''//List to dump images into
Dim Images As New List(Of Byte())
''//Main PDF reader
Dim Reader As New PdfReader(InputFile)
''//Total number of pages in the PDF
Dim PageCount = Reader.NumberOfPages
''//Loop through each page (first page is one, not zero)
For I = 1 To PageCount
getAllImages(Reader.GetPageN(I), Images, Reader)
Next
非常非常重要-iTextSharp是不是一个PDF渲染器,它是一个PDF编写器。这意味着它知道它有像图像一样的对象,但它不一定对它们了解很多。换一种说法,iTextSharp知道给定的字节数组表示PDF标准所说的图像,但它不知道或不关心是JPEG、TIFF、BMP还是其他格式。iTextSharp所关心的是,该对象具有一些它可以操纵的标准属性,如X、Y和有效宽度和高度。PDF渲染器将处理将字节转换为实际图像的工作。在这种情况下,您是PDF渲染器,因此您的工作是找出如何将字节数组处理为图像
具体来说,您将在该方法中看到一行内容:
If filter = "/FlateDecode" Then
这通常写为select case
或switch
语句,以处理filter
的各种值。您所引用的方法仅处理FlateDecode
,这是非常常见的,尽管实际上有10个标准过滤器,例如CCITTFaxDecode
、JBIG2Decode
和DCTDecode
(PDF Spec 7.4-过滤器)。您应该修改该方法以包含某种类型的捕获(一个Else
或Default
案例),这样您至少可以知道未设置要处理的图像
此外,在/FlatDecode
部分中,您将看到这一行:
Select Case Integer.Parse(bpp)
这是读取与图像对象关联的属性,该属性告诉渲染器在解析时每个颜色应使用多少位。同样,在本例中,您是PDF渲染器,因此由您自己决定要做什么。您引用的代码只考虑单色(1bpp)或真彩色(24bpp)图像,但其他图像肯定要考虑,尤其是8bpp
所以总结一下,希望代码能按原样为您工作,但是如果它抱怨很多和/或遗漏了图像,请不要感到惊讶。提取图像有时会非常令人沮丧。如果您遇到问题,请在这里开始一个新问题,并引用此问题,希望我们能为您提供更多帮助 当引用在别处找到的代码时,请包含引用源代码的链接。通常情况下,来源有答案,我们不必每次都重新发明轮子。