Discussion:
[iText-questions] Replace images in pdf
breegee
2015-12-21 19:06:25 UTC
Permalink
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()



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

------------------------------------------------------------------------------
_______________________________________________
iText-questions mailing list
iText-***@lists.sourceforge.net
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
m***@verizon.net
2015-12-21 19:42:22 UTC
Permalink
------------------------------------------------------------------------------
mkl
2015-12-22 08:19:03 UTC
Permalink
Post by 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.
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




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

------------------------------------------------------------------------------
_______________________________________________
iText-questions mailing list
iText-***@lists.sourceforge.net
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
breegee
2015-12-22 14:20:34 UTC
Permalink
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
iText-***@lists.sourceforge.net
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
2015-12-22 15:45:39 UTC
Permalink
Post by breegee
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?



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

------------------------------------------------------------------------------
_______________________________________________
iText-questions mailing list
iText-***@lists.sourceforge.net
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
breegee
2015-12-22 16:22:35 UTC
Permalink
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
iText-***@lists.sourceforge.net
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
2015-12-23 18:06:47 UTC
Permalink
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?
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.



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

------------------------------------------------------------------------------
_______________________________________________
iText-questions mailing list
iText-***@lists.sourceforge.net
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
Loading...