on 07-04-2012 10:02 AM
Hi all,
I'm receiving a PDF file into PI. Would be possible to get a Watermark, and merge it with the received PDF file and return the file modified?
Thanks in advance.
Regards.
Urtzi
Yes it is possible. You can try using java mapping or UDF. You might want to try using Java iText PDF tool. The link is given below. You will also find the code example in the same page.
http://thinktibits.blogspot.com/2011/04/java-itext-pdf-add-watermark-example.html
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi both,
Iñaki, I'm afraid we don't have PE for your proposal.
Gref, UDF would be fine, but how I 'change' your code to UDF in mapping?
Because I'm having some syntax errors...I'm not very good in JAVA, my world is ABAP...:-)
Thanks in advance.
Best REgards.
Urtzi.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
As per bhaskar suggested, use the itextPDF jar files
download the jar files zipped from: http://sourceforge.net/projects/itext/files/iText/iText5.3.0/
extract the zip file and use itextpdf-5.3.0.jar & itext-xtra-5.3.0.jar in your java code classpath for compiling. You need to import these jar files along with java class file as an import archive in PI.
UDF will not work in your case if the incoming payload is binary i.e., PDF. Hence you need to proceed with java mapping in that case. If PDF document is coming as an extra attachment, then you can handle this in graphical mapping using a UDF.
Hi Urtzi,
Use this code as java mapping, I tested this and it is working.
import java.io.*;
import java.util.Map;
import java.util.HashMap;
import java.util.*;
import java.util.zip.*;
import javax.swing.ImageIcon;
import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.api.*;
import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;
import com.sap.aii.mapping.api.StreamTransformationException;
import java.io.FileOutputStream;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
public class WaterMarkJM extends AbstractTransformation
{
static final int BUFFER = 1024*1000;
private Map param;
public WaterMarkJM(){ }
public void setParameter (Map map)
{
param = map;
if (param == null)
{
param = new HashMap();
}
}
public static void main(String args[])
{
try
{
FileInputStream fin = new FileInputStream(args[0]);
FileOutputStream fout = new FileOutputStream(args[1]);
WaterMarkJM mapping = new WaterMarkJM();
mapping.execute(fin, fout);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void transform(TransformationInput arg0, TransformationOutput arg1) throws StreamTransformationException
{
this.execute( (InputStream) arg0.getInputPayload().getInputStream(), (OutputStream) arg1.getOutputPayload().getOutputStream());
}
public void execute(InputStream inputstream, OutputStream outputstream)
{
try {
PdfReader Read_PDF_To_Watermark = new PdfReader(inputstream);
int number_of_pages = Read_PDF_To_Watermark.getNumberOfPages();
PdfStamper stamp = new PdfStamper(Read_PDF_To_Watermark, outputstream);
int i = 0;
InputStream in = getClass().getResourceAsStream("<watermark.jpg>"); //NOTE: load your WATERMARK image as part of archive
int len = 0;
byte[] buffer = new byte[BUFFER];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
while ((len = in.read(buffer)) > 0)
{
baos.write(buffer, 0, len);
}
Image watermark_image = Image.getInstance(baos.toByteArray());
watermark_image.setAbsolutePosition(200, 400);
PdfContentByte add_watermark;
while (i < number_of_pages) {
i++;
add_watermark = stamp.getUnderContent(i);
add_watermark.addImage(watermark_image);
}
stamp.close();
}
catch (Exception i1) {
i1.printStackTrace();
}
}
}
As I mentioned earlier, download the itextPDF jar files zip from: http://sourceforge.net/projects/itext/files/iText/iText5.3.0/
extract the zip file and use itextpdf-5.3.0.jar & itext-xtra-5.3.0.jar in your java code classpath for compiling. You need to import these jar file contents along with above WaterMarkJM java class file and your water mark image (zipped file) as an imported archive in PI.
The folder structure for your class file, image file and Itext PDF jar files should look like as below, and these contents need to be zipped and loaded into PI as an imported archive
Now you can download the jar file and directly use it in your interface mapping: https://www.box.com/s/5b56f8ca3955c747c900
Also note that your imported archive should look like this when imported into PI
Best Regards,
Praveen Gujjeti
Updated with developed archive: https://www.box.com/s/5b56f8ca3955c747c900 Message was edited by: Praveen Gujjeti
Hi Praveen,
Very helpful your JARS.zip file, thank you very much!
I've imported .zip as you mentioned, but executing scenario I'm getting mapping error:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
- <!--
Request Message Mapping
-->
</SAP:Error>
Thanks in advance!
Best Regards.
Urtzi.
Hi Praveed!
I was just updating the status. I've compiled with 1.5 and now I'm getting:
Unable to find resource c2e6ebe0-a010-11e1-9832-de440ac8224a in the following software component versions: http://com.ide.watermarkJars/WaterMarkJM.class-1
Thanks!
Urtzi.
Hi Praveen,
I've deleted all objects and begin again, with new compilation with same version. Now I'm getting:
</SAP:Error>
regards.
Urtzi.
Hi Praveen,
I've followed this post:
http://scn.sap.com/thread/2019178
And Zip JAVA class without folder, and now I'm getting:
</SAP:Error>
Sorry my mistake,
Take this updated one, it will work directly work for you. In my previous one I considered Jars as root directory and hence the error.
Hi Praveen,
Thank you very much for your library, now I can do the call.
My doubt is, how have you defined de Message Types? I mean, how is the mapping returning the doc with watermark?
I'm getting an error because the payload has not the correct structure. In Moni the payload:
Thanks a lot!
Regards.
Urtzi.
Messge type/ message interface structure can be anything. it does not matter since you are working with a java mapping.
Message interface can carry any message (text/binary) irrespective of its structure. graphical mapping fails because it does a validation using SAX parser
>> I'm getting an error because the payload has not the correct structure. In Moni the payload:
what is the incoming payload type? i believe it should be a PDF as per your requiement. are you able to see embedded PDF in MONI for the incoming message.
Hmm. looks like this one is BASE64 encoded one. you need to decode and pass it to your java mapping as input.
Read my WIKI, which helps in decoding the it in java mapping
go to section Java Mapping - Base64 Decryption and Unzipping Code
wiki.sdn.sap.com/wiki/display/XI/Sending+Binary+Data+to+Inbound+Plain+HTTP+Adapter+in+XI+and+PI
Hi Praveen,
I'm reading PDF file from Content Server in SAP, or with GUI_UPLOAD method of cl_gui_frontend_services, in Binary.
My issue is that I'm calling PI to set the WaterMark using RFC call:
CALL FUNCTION 'Z_WATERMARK'
DESTINATION 'PI'
EXPORTING
pi_file = output
IMPORTING
pe_file = result.
Where the original file us in output and the target file, with watermark included, is suposed to be in result.
Both are STRING type (I also tried with XSTRING, string in binary)¨.
How does it afect to your mapping? I'm not saying anywhere that I want the file in result field.
Thanks!
Urtzi.
I am not clear about the scneario flow. Do you mean you already developed ABAP wrapper "Z_WATERMARK" in PI already and using that you want to add a water mark?
can you tell us your scneario flow?
Remote functional modules can not handle binaries directly and hence they will converted to BASE64 format.
I have a requirement to set watermark to PDFs.
The files are in a content server, and now I'm reading them with RFC modules and send to SAP.
But if it is not posible, I can do a workaround: I can put the PDF in a folder and PI can take the file with a File Adapter...
Is like that your scenario?
Thanks!
Urtzi Barandiaran Aguirre wrote:
I have a requirement to set watermark to PDFs.
The files are in a content server, and now I'm reading them with RFC modules and send to SAP.
But if it is not posible, I can do a workaround: I can put the PDF in a folder and PI can take the file with a File Adapter...
Is like that your scenario?
Thanks!
It should be possible with RFC adapter/ABAP proxy as well. If you have a file option then please proceed.
Hi Praveen,
Finally I get the watermark in PDF file with your class, thanks!
Now I have three more challenges for you...:-)
- It is possible to say where exactly I want the watermark in the PDF file? and set transparency in order to the document can be read¿?
- Would be possible to set watermark dinamically at runtime? not always same jpg¿
- Would be possible Watermark be another PDF file in order of JPG?
If you prefer I can open separete threads.
Thank you very much in advance!
REgards.
Urtzi.
Hi Urtzi.,
Glad to hear
>> It is possible to say where exactly I want the watermark in the PDF file? and set transparency in order to the document can be read¿?
Yes it should be possible, please read the IText API.
>> Would be possible to set watermark dinamically at runtime? not always same jpg¿
Yes it is possible. But how you are planning to send the image? I mean as attachment or some where placing it in PI system local directory etc..
>> Would be possible Watermark be another PDF file in order of JPG?
I did not understand your question fully. Can you please elaborate.
Also, please tell your secnario flow e.g., source system --> xi --> target system
- Praveen
Hi Praveen,
My scenario is:
I have to take a PDF file from a Content Server and set Watermark.
To get file from Content Server I was thinking to use SAP RFC and get the file in binary, but you told me las week that was not a good idea...
I don't mind if I put the file in a directory and PI takes it.
THe Watermark image should be an attachment because I have to build it at runtime.
Final issue, I mean that a requirement is that the Watermar not to be i.e. Watermark.JPG (an image), but yes other PDF file, Watermark.PDF.
So there will be 2 PDF files:
- Watermark.PDF
- OriginalFile.PDF
And the result should be a PDF file with Watermark.PDF 'inside' OriginalFile.PDF' as watermark.
Thanks!
Regards.
Urtzi.
Praveen,
How do you export im Developer Studio with no Path in class¿?
If I modify your files, I get:
<SAP:Retry>M</SAP:Retry>
</SAP:Error>
Thanks!
Urtzi.
Hi Urtzi,
New code which can handle image from PDF (Watermark PDF) and then stamp it on the incoming PDF file. It can also set opacity (or) transparency for the loaded image.
import java.io.*;
import java.util.Map;
import java.util.HashMap;
import java.util.*;
import java.util.zip.*;
import javax.swing.ImageIcon;
import com.sap.aii.mapping.api.AbstractTrace;
import com.sap.aii.mapping.api.*;
import com.sap.aii.mapping.api.AbstractTransformation;
import com.sap.aii.mapping.api.TransformationInput;
import com.sap.aii.mapping.api.TransformationOutput;
import com.sap.aii.mapping.api.StreamTransformationException;
import java.io.FileOutputStream;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfObject;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfStream;
import com.itextpdf.text.pdf.PRStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.ImageFilter;
import java.awt.image.ImageProducer;
import java.awt.image.RGBImageFilter;
import javax.imageio.ImageIO;
public class WaterMarkWithPDFJM extends AbstractTransformation
{
static final int BUFFER = 1024*1000;
private Map param;
private AbstractTrace trace = null;
TransformationInput transformationInput = null;
InputAttachments inputAttachments = null;
public WaterMarkWithPDFJM(){ }
public void setParameter (Map map)
{
param = map;
if (param == null)
{
param = new HashMap();
}
}
// Method BufferedImage loadTranslucentImage(BufferedImage image, float transperancy) for making an Image Translucent
// Courtesy: http://www.javalobby.org/articles/ultimate-image/#7
//Author: Josiah Hester
public static BufferedImage loadTranslucentImage(BufferedImage image, float transperancy)
{
BufferedImage aimg = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TRANSLUCENT);
// Get the images graphics
Graphics2D g = aimg.createGraphics();
// Set the Graphics composite to Alpha
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, transperancy));
// Draw the LOADED img into the prepared reciver image
g.drawImage(image, null, 0, 0);
// let go of all system resources in this Graphics
g.dispose();
// Return the image
return aimg;
}
public static void main(String args[])
{
try
{
FileInputStream fin = new FileInputStream(args[0]);
FileOutputStream fout = new FileOutputStream(args[1]);
WaterMarkWithPDFJM mapping = new WaterMarkWithPDFJM();
mapping.execute(fin, fout);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void transform(TransformationInput arg0, TransformationOutput arg1) throws StreamTransformationException
{
transformationInput = arg0;
inputAttachments = arg0.getInputAttachments();
this.getTrace().addInfo("in Transform Method");
this.execute( (InputStream) arg0.getInputPayload().getInputStream(), (OutputStream) arg1.getOutputPayload().getOutputStream());
}
public void execute(InputStream inputstream, OutputStream outputstream)
{
try {
if (transformationInput != null)
this.getTrace().addInfo("in execute method");
Image watermark_image = null;
BufferedImage transpImg3 = null;
Object[] arrayObj = null;
String attachmentID = null;
byte[] attachmentBytes = null;
InputStream in = null;
PdfReader reader = null;
if (transformationInput != null)
{
this.getTrace().addInfo("Transofrmation Input not null");
if( inputAttachments != null )
{
if( inputAttachments.areAttachmentsAvailable() )
{
this.getTrace().addInfo("Attachments available. Hence Reading watermark PDF image from attachments");
//gets the attachmentIds and store it in an Object array
Collection<String> collectionIDs = inputAttachments.getAllContentIds(true);
arrayObj = collectionIDs.toArray();
String contentIDS = "";
for(int attCounter =0;attCounter < arrayObj.length; attCounter++)
{
attachmentID =(String)arrayObj[attCounter];
Attachment attachment = inputAttachments.getAttachment(attachmentID);
attachmentBytes = attachment.getContent();
reader = new PdfReader(attachmentBytes);
}
}
else
this.getTrace().addInfo("Attachments not available");
}
else
{
this.getTrace().addInfo("Attachments not available. Hence Reading watermark PDF image from imported archive");
in = (InputStream) getClass().getResourceAsStream("Watermark.pdf");
reader = new PdfReader(in);
}
}
else //in Standalone mode
{
System.out.println("In Standalone mode: Reading resource file \"Watermark.pdf\" from current working directoy");
in = (InputStream) getClass().getResourceAsStream("Watermark.pdf");
reader = new PdfReader(in);
}
PdfReader Read_PDF_To_Watermark = new PdfReader(inputstream);
int number_of_pages = Read_PDF_To_Watermark.getNumberOfPages();
PdfStamper stamp = new PdfStamper(Read_PDF_To_Watermark, outputstream);
int i = 0;
for (int j = 0; j < reader.getXrefSize(); j++)
{
PdfObject pdfobj = reader.getPdfObject(j);
if (pdfobj == null || !pdfobj.isStream()) {
continue;
}
PdfStream stream = (PdfStream) pdfobj;
PdfObject pdfsubtype = stream.get(PdfName.SUBTYPE);
if (pdfsubtype != null && pdfsubtype.toString().equals(PdfName.IMAGE.toString()))
{
byte[] img = PdfReader.getStreamBytesRaw((PRStream) stream);
InputStream is = new ByteArrayInputStream( img );
BufferedImage image = ImageIO.read(is);
transpImg3 = loadTranslucentImage(image, 0.2f); // Set transparency or opacity here e.g. 0.3f etc..
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(transpImg3, "PNG", baos); // sj
watermark_image = Image.getInstance(baos.toByteArray());
watermark_image.setAbsolutePosition( (int) watermark_image.getAbsoluteX() , (int) watermark_image.getAbsoluteY() );
}
}
PdfContentByte add_watermark;
while (i < number_of_pages)
{
i++;
add_watermark = stamp.getUnderContent(i);
add_watermark.addImage(watermark_image);
}
stamp.close();
}
catch (Exception i1) {
i1.printStackTrace();
this.getTrace().addDebugMessage(i1.toString());
}
}
}
- Praveen
Hi Urtzi,
You should consider your enviroment infraestructure before to use SAP PI for this purpose. For example if you have got a SAN Netweaver Portal you could follow this solution http://scn.sap.com/docs/DOC-7196
In the case that you use a PI, you will use a file to file scenario, you can use the link pointed by Greg, but you should consider if the watermark picture will be stored in PI directory or you want to receive this image as well, then the java code and the mergue process can have several changes.
Regards.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi,
This should be possible with some Java code, for instance as described here:
http://www.java2s.com/Code/Java/PDF-RTF/AddWatermarkImagetoanExistingPDFFile.htm
You can include this code in a UDF, Java mapping or Adapter Module, depending on the other requirements for your scenario.
Regards,
Greg
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
User | Count |
---|---|
76 | |
9 | |
8 | |
7 | |
6 | |
5 | |
5 | |
5 | |
5 | |
5 |
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.