Quantcast

Replace images in pdf

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Replace images in pdf

breegee
I am trying to replace a particular image on several pages in a pdf. It runs through the code fine but when I open the file I see the first image replaced and when I scroll to the second page it says there is an error in the pdf.  Can anyone help me figure out what I am doing wrong?  Thank you.

        Dim reader = New iTextSharp.text.pdf.PdfReader(sourcePdf)
        Dim pdfStamper = New PdfStamper(reader, New FileStream(newFile, FileMode.Create))
        Dim writer = pdfStamper.Writer

        Dim page_count As Integer = reader.NumberOfPages
        Dim i As Integer = 1
        Do While (i <= page_count)
            Dim pg As PdfDictionary = reader.GetPageN(i)
            Dim res As PdfDictionary = CType(PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES)), PdfDictionary)
            Dim xobj As PdfDictionary = CType(PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT)), PdfDictionary)
            If (Not (xobj) Is Nothing) Then
                For Each name As PdfName In xobj.Keys
                    Dim obj As PdfObject = xobj.Get(name)
                    If obj.IsIndirect Then
                        Dim tg As PdfDictionary = CType(PdfReader.GetPdfObject(obj), PdfDictionary)
                        Dim type As PdfName = CType(PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)), PdfName)
                        If PdfName.IMAGE.Equals(type) Then
                            If tg.GetAsNumber(pdf.PdfName.WIDTH).IntValue = 61 Then
                                Dim xrefIdx As Integer = CType(obj, PRIndirectReference).Number
                                Dim pdfObj As PdfObject = reader.GetPdfObject(xrefIdx)
                                Dim maskImage As Image = Image.ImageMask
                                If (Not (maskImage) Is Nothing) Then
                                    writer.AddDirectImageSimple(maskImage)
                                End If
                                PdfReader.KillIndirect(obj)
                                writer.AddDirectImageSimple(Image, obj)
                                Exit For
                            End If
                        End If
                    End If

                Next
            End If

            i = (i + 1)
        Loop

        pdfStamper.Writer.CloseStream = False
        pdfStamper.Close()
        reader.Close()

------------------------------------------------------------------------------

_______________________________________________
iText-questions mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/itext-questions

iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replace images in pdf

mkl
breegee wrote
I am trying to replace a particular image on several pages in a pdf. It runs through the code fine but when I open the file I see the first image replaced and when I scroll to the second page it says there is an error in the pdf.
Unfortunately you did not share your PDF, so one has to guess a bit.

Two possible reasons:

* The same image object is referenced from page 1 and page 2. Your code replaces the reference on page one and kills the object. On page two your code does nothing to the image reference as (due to your killing the image object before) the reference goes to null. The PDF viewer later, when trying to display page two, finds this image reference pointing nowhere and complains.

* You use "pdfStamper.Writer.CloseStream = False", thus "pdfStamper.Close()" does not implicitly close your stream. I also don't see you explicitly closing that stream. Depending on the circumstances this might indeed result in a damaged result file (the CloseStream flag predominantly is intended for use with MemoryStreams, not with FileStreams; due to buffering FileStreams may behave funny if not closed.)

Regards,   Michael
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replace images in pdf

breegee
mkl, I believe you are right with this one...
The same image object is referenced from page 1 and page 2. Your code
replaces the reference on page one and kills the object. On page two your
code does nothing to the image reference as (due to your killing the image
object before) the reference goes to null. The PDF viewer later, when trying
to display page two, finds this image reference pointing nowhere and
complains.


If I wrap the killindirect in 'if i = 1 then killindirect', only doing it on
page 1, then there is no error in my pdf.  But it's not replacing my image
on page 2 also.



--
View this message in context: http://itext.2136553.n4.nabble.com/Replace-images-in-pdf-tp4660966p4660968.html
Sent from the iText mailing list archive at Nabble.com.

------------------------------------------------------------------------------
_______________________________________________
iText-questions mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/itext-questions

iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replace images in pdf

mkl
breegee wrote
If I wrap the killindirect in 'if i = 1 then killindirect', only doing it on
page 1, then there is no error in my pdf.  But it's not replacing my image
on page 2 also.
I would propose not killing the objects at all while you are in the loop but instead adding them to some collection.

After finishing the loop you can iterate over that collection and kill the objects, but do make sure you don't try to kill the same object twice.

Regards,   Michael.

BTW, you are aware that your code does only replace images directly referenced from the page content, and that it completely ignores those in included form xobjects and patterns, and also inlined images?
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replace images in pdf

breegee
In reply to this post by breegee
I changed it to use a stream and it works as far as replacing all of my
images with no error on the pdf.  However, the imaging I am putting in place
shows with a black background. Not sure why or how to fix that.  Any
suggestions?

Do While (i <= page_count)
            Dim pg As PdfDictionary = reader.GetPageN(i)
            Dim res As PdfDictionary =
CType(PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES)), PdfDictionary)
            Dim xobj As PdfDictionary =
CType(PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT)), PdfDictionary)
            If (Not (xobj) Is Nothing) Then
                For Each name As PdfName In xobj.Keys
                    Dim obj As PdfObject = xobj.Get(name)
                    If obj.IsIndirect Then
                        Dim tg As PdfDictionary =
CType(PdfReader.GetPdfObject(obj), PdfDictionary)
                        Dim type As PdfName =
CType(PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE)), PdfName)
                        If PdfName.IMAGE.Equals(type) Then
                            If tg.GetAsNumber(pdf.PdfName.WIDTH).IntValue =
61 Then
                                Dim stream As PRStream =
CType(xobj.GetAsStream(name), PRStream)
                                Dim maskImage As Image = ImageSign.ImageMask
                                Dim image As PdfImage = New
PdfImage(maskImage, "", Nothing)
                                ReplaceStream(stream, image)
                                Exit For
                            End If
                        End If
                    End If

                Next
            End If

            i = (i + 1)
        Loop

    Public Shared Sub ReplaceStream(ByVal oldimage As PRStream, ByVal
newstream As PdfStream)
        oldimage.Clear()
        Dim ms As MemoryStream = New MemoryStream
        newstream.WriteContent(ms)
        oldimage.SetData(ms.ToArray(), False)
        For Each keyValuePair As KeyValuePair(Of PdfName, PdfObject) In
newstream
            oldimage.Put(keyValuePair.Key, newstream.Get(keyValuePair.Key))
        Next
    End Sub



--
View this message in context: http://itext.2136553.n4.nabble.com/Replace-images-in-pdf-tp4660966p4660972.html
Sent from the iText mailing list archive at Nabble.com.

------------------------------------------------------------------------------
_______________________________________________
iText-questions mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/itext-questions

iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Replace images in pdf

mkl
breegee wrote
I changed it to use a stream and it works as far as replacing all of my
images with no error on the pdf.  However, the imaging I am putting in place
shows with a black background. Not sure why or how to fix that.  Any
suggestions?
Please share the image for analysis.

Please be aware that most image formats are not supported as is in PDFs but are converted to a PDF specific bitmap format which in particular stores transparency as a separate grayscale image.

Regards,   Michael.
Loading...