Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在.net中提取图像代码,我可以';我不能让它工作_.net_Itextsharp - Fatal编程技术网

在.net中提取图像代码,我可以';我不能让它工作

在.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)),

我想简单地从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)), 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


所以总结一下,希望代码能按原样为您工作,但是如果它抱怨很多和/或遗漏了图像,请不要感到惊讶。提取图像有时会非常令人沮丧。如果您遇到问题,请在这里开始一个新问题,并引用此问题,希望我们能为您提供更多帮助

当引用在别处找到的代码时,请包含引用源代码的链接。通常情况下,来源有答案,我们不必每次都重新发明轮子。