How to make stamped image uneditable using iTextSharp?

764 Views Asked by At

My goal is stamp an image on a 3D PDF that behaves like a watermark (end-user cannot select, edit, resize, or delete the image).

I tried making an Annotation as shown below, but the image ("ClassificationBlock.png" in Resources) can be resized and deleted on the output PDF. Is that an inherent behavior of "PdfAnnotation" rectangles or is there a property I can define that will keep the image essentially read-only?

using (PdfStamper stamp = new PdfStamper(reader, fs))

. . .

                Rectangle stampRect2 = null;

                System.Drawing.Image imageBTM2 = System.Drawing.Image.FromHbitmap(Properties.Resources.ClassificationBlock.GetHbitmap());
                Image stampImage2 = iTextSharp.text.Image.GetInstance(imageBTM2, System.Drawing.Imaging.ImageFormat.Png);

                Rectangle location2 = new Rectangle(0, 0, stampImage2.Width, stampImage2.Height);
                PdfAnnotation pdfStamp2 = PdfAnnotation.CreateStamp(stamp.Writer, location2, null, "ImageText");
                stampImage2.SetAbsolutePosition(0, 0);
                PdfAppearance app2 = stamp.GetOverContent(1).CreateAppearance(stampImage2.Width, stampImage2.Height);
                app2.AddImage(stampImage2);
                pdfStamp2.SetAppearance(PdfName.N, app2);
                pdfStamp2.SetPage();
                stamp.AddAnnotation(pdfStamp2, 1);
                stampRect2 = location2;

                stamp.FormFlattening = true;

                stamp.Close();
                reader.Close();
                fs.Close();

I've also tried it by mimicking another user's attempt at watermark text via pdfContentBytes, but I can't get the image to even display on the PDF.

                    stamp.FormFlattening = false;
                    iTextSharp.text.Rectangle pageRectangle = reader.GetPageSizeWithRotation(1);
                    PdfContentByte pdfData = stamp.GetOverContent(1);
                    pdfData.SetFontAndSize(BaseFont.CreateFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.NOT_EMBEDDED), 10);
                    PdfGState graphicsState = new PdfGState();
                    graphicsState.FillOpacity = 0.5F;
                    pdfData.SetGState(graphicsState);
                    pdfData.BeginText();

                    System.Drawing.Image imageBTM2 = System.Drawing.Image.FromHbitmap(Properties.Resources.TEKLAPDF_InstructionBlock.GetHbitmap());
                    iTextSharp.text.Image stampImage2 = iTextSharp.text.Image.GetInstance(imageBTM2, System.Drawing.Imaging.ImageFormat.Png);

                    float width = pageRectangle.Width;
                    float height = pageRectangle.Height;
                    stampImage2.ScaleToFit(width, height);
                    stampImage2.SetAbsolutePosition(width / 2 - stampImage2.Width / 2, height / 2 - stampImage2.Height / 2);
                    stampImage2.SetAbsolutePosition(50, 50);
                    stampImage2.Rotation = 0;

                    pdfData.AddImage(stampImage2);

                    pdfData.EndText();

Any ideas on how best to accomplish this? This is driving me crazy.

EDIT*****************************

These are the current avenues I've pursued. Any ideas on how to "watermark" the 3D PDF?

                //Stamp Image Method (works on 2D PDF and 3D PDF BUT results in EDITABLE stamp) 

                System.Drawing.Image imageBTM2 = System.Drawing.Image.FromHbitmap(Properties.Resources.ClassificationBlock.GetHbitmap());
                Image stampImage2 = iTextSharp.text.Image.GetInstance(imageBTM2, System.Drawing.Imaging.ImageFormat.Png);

                Rectangle stampRect2 = null;
                Rectangle location2 = new Rectangle(0, 0, stampImage2.Width, stampImage2.Height);
                PdfAnnotation pdfStamp2 = PdfAnnotation.CreateStamp(stamp.Writer, location2, null, "ImageText");
                stampImage2.SetAbsolutePosition(0, 0);
                PdfAppearance app2 = stamp.GetUnderContent(1).CreateAppearance(stampImage2.Width, stampImage2.Height);
                app2.AddImage(stampImage2);
                pdfStamp2.SetAppearance(PdfName.N, app2);
                pdfStamp2.SetPage();
                stamp.AddAnnotation(pdfStamp2, 1);
                stampRect2 = location2;


                //Watermark Layering Method (works only on 2D PDF)
                var layers = stamp.GetPdfLayers();

                var imgLayer = new PdfLayer("StackoverflowImage", stamp.Writer);
                PdfContentByte cb = stamp.GetUnderContent(1);
                cb.BeginLayer(imgLayer);

                stampImage2.ScalePercent(100f);
                stampImage2.SetAbsolutePosition(pageWidth/2, pageHeight/2);
                cb.AddImage(stampImage2);

                cb.EndLayer();


                //Jan's Watermark method (works only on 2D PDF)

                PdfContentByte over = stamp.GetOverContent(1);
                stampImage2.SetAbsolutePosition(pageWidth / 2, pageHeight / 2);
                PdfLayer imgLayer = new PdfLayer("StackoverflowImage", stamp.Writer);
                imgLayer.OnPanel = false;
                over.BeginLayer(imgLayer);
                over.AddImage(stampImage2);
                over.EndLayer();


                stamp.Close();
                reader.Close();
2

There are 2 best solutions below

8
On

First off: You most likely cannot prevent selection of the image.

Second: I do itext in Java, so you'll probably end up uppercasing first character of method names...

For the remainder or your question you could try to add this image to a layer:

    PdfContentByte over = stamp.getOverContent(1)
    Image img = ...//code to get your image;
    img.setAbsolutePosition(x, y); //at your postion
    PdfLayer imgLayer = new PdfLayer("StackoverflowImage", stamper.getWriter());
    imgLayer.setOnPanel(false);
    over.beginLayer(imgLayer);
    over.addImage(img);
    over.endLayer();
0
On

SOLVED! Using the "Stamp Image Method" as described above, I just needed to change the properties of the stamp itself (changing FLAGS to LOCKED and READ-ONLY). This results in a stamp that is above the 3D PDF layer AND cannot be resized, edited, or deleted. So the code is now:

                //Stamp Image Method 

                System.Drawing.Image imageBTM2 = System.Drawing.Image.FromHbitmap(Properties.Resources.ClassificationBlock.GetHbitmap());
                Image stampImage2 = iTextSharp.text.Image.GetInstance(imageBTM2, System.Drawing.Imaging.ImageFormat.Png);

                Rectangle stampRect2 = null;
                Rectangle location2 = new Rectangle(0, 0, stampImage2.Width, stampImage2.Height);
                PdfAnnotation pdfStamp2 = PdfAnnotation.CreateStamp(stamp.Writer, location2, null, "ImageText");

                pdfStamp2.Flags = iTextSharp.text.pdf.PdfAnnotation.FLAGS_LOCKED;
                pdfStamp2.Flags = iTextSharp.text.pdf.PdfAnnotation.FLAGS_READONLY;

                stampImage2.SetAbsolutePosition(0, 0);
                PdfAppearance app2 = stamp.GetUnderContent(1).CreateAppearance(stampImage2.Width, stampImage2.Height);
                app2.AddImage(stampImage2);
                pdfStamp2.SetAppearance(PdfName.N, app2);
                pdfStamp2.SetPage();
                stamp.AddAnnotation(pdfStamp2, 1);
                stampRect2 = location2;