and in debug what i found that actually file read ,seeek are set to false after pdfreader read the stream.
rahularyansharma asked Mar 21, 2017 at 7:04 rahularyansharma rahularyansharma 10.7k 18 18 gold badges 82 82 silver badges 138 138 bronze badgesIt's quite simple: Whenever a PdfReader is constructed from a Stream , that stream is closed after being read to the end. Thus, after
PdfReader pdfReader = new PdfReader(pdfStream);
Yes, this does contradict the source code comment which claims "The stream is read to the end but is not closed":
/** * Reads and parses a PDF document. * @param isp theInputStream
containing the document. The stream is read to the * end but is not closed * @throws IOException on error */ public PdfReader(Stream isp) : this(isp, null) < >/** * Reads and parses a PDF document. * @param is theInputStream
containing the document. The stream is read to the * end but is not closed * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(Stream isp, byte[] ownerPassword) : this( new RandomAccessSourceFactory().CreateSource(isp), false, ownerPassword, null, null, false)
But looking at the used RandomAccessSourceFactory method CreateSource overload one sees:
/** * Creates a based on an . The full content of the InputStream is read into memory and used * as the source for the * @param is the stream to read from * @return the newly created */ public IRandomAccessSource CreateSource(Stream inp) < try < return CreateSource(StreamUtil.InputStreamToArray(inp)); >finally < try catch<> > >
I.e. an enforced Close .
That been said, if the file was not closed, you would merely have a different exception.
PdfReader pdfReader = new PdfReader(pdfStream);
the stream is read to the end, so here
var image = iTextSharp.text.Image.GetInstance(pdfStream);
there would be nothing to read from the stream.
And even if you did reset the stream to the start before Image.GetInstance , you would get yet another exception: Either the stream content is a PDF or a bitmap image. If it is a PDF, Image.GetInstance will fail; if it is a bitmap, new PdfReader will fail (assuming you don't use one of those constructed files which are both accepted as a bitmap and as a PDF by means of meshing the formats)
Concerning your task to write some text above images in the file, you can do that by creating a custom render listener (instead of using an existing one which ignores the image coordinates), e.g. like this:
public class ImageEntitlingRenderListener : IRenderListener < BaseFont baseFont = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1250, BaseFont.NOT_EMBEDDED); PdfStamper pdfStamper = null; int page = 0; public ImageEntitlingRenderListener(PdfStamper pdfStamper, int page) < this.pdfStamper = pdfStamper; this.page = page; >public void RenderImage(ImageRenderInfo renderInfo) < Matrix ctm = renderInfo.GetImageCTM(); float xCenter = ctm[Matrix.I31] + 0.5F * ctm[Matrix.I11]; float yTop = ctm[Matrix.I32] + ctm[Matrix.I22]; PdfContentByte pdfContentByte = pdfStamper.GetOverContent(page); pdfContentByte.SetColorFill(BaseColor.BLUE); pdfContentByte.SetFontAndSize(baseFont, 8); pdfContentByte.BeginText(); pdfContentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "rahul", xCenter, yTop, 0); pdfContentByte.EndText(); >public void BeginTextBlock() < >public void EndTextBlock() < >public void RenderText(TextRenderInfo renderInfo) < >>
You can use it like this:
private static void InsertTextToPdf(string sourceFileName, string newFileName) < using (Stream pdfStream = new FileStream(sourceFileName, FileMode.Open)) using (Stream newpdfStream = new FileStream(newFileName, FileMode.Create, FileAccess.ReadWrite)) < PdfReader pdfReader = new PdfReader(pdfStream); PdfStamper pdfStamper = new PdfStamper(pdfReader, newpdfStream); var parser = new PdfReaderContentParser(pdfReader); for (var i = 1; i pdfStamper.Close(); pdfReader.Close(); > >
Beware, there are some simplifying assumptions in the code. In particular it assumes that images are drawn upright in the PDF. You might want to improve the code for a more generic use.