From: Lumpia on
cfSearching,

Something appears to be off as it is still not adjusting for 2 different
images at different yOffset positions. I'm not getting an error, just a
previous pdf merge instead. You stated that this code:

<cfset variables.img =
javaLoader.create("com.lowagie.text.Image").getInstance(
variables.fullPathToImage1 )>
<cfset variables.yOffset = variables.yOffset + variables.img.getHeight()>

takes into account the size of the first image and readjusts the yOffset
accordingly. Essentially, could I not just 2 different yOffsets like so:

<cfset variables.xOffset = 160>
<cfset variables.yOffset = 20>

<cfif len(trim(form.image1)) >
<!--- NOTE - these should be absolute paths --->
<cfset insertWatermarkPDF( fullPathToInputFile
, fullPathToImage1
, fullPathToOutputFile1
, variables.xOffset
, variables.yOffset
, 1
)>
</cfif>

<cfset variables.xOffset = 160>
<cfset variables.yOffset = 30>

<cfif len(trim(form.image2)) >
<!--- NOTE - these should be absolute paths --->
<cfset insertWatermarkPDF( fullPathToOutputFile1
, fullPathToImage2
, fullPathToOutputFile2
, variables.xOffset
, variables.yOffset
, 1
)>
</cfif>

Regardless of how I modify the code, it still wants to overlap the images.
Correct me if I'm wrong, but it seems like the code within the function
(img.setAbsolutePosition(xPos, yPos)) needs to be adjusted to account if there
are 2 images.

for ( ii = 1; ii LTE totalPages; ii = ii + 1)
{
...
box = reader.getCropBox( javacast("int", ii) );
// calculate the x and y postions based on the given offsets
xPos = box.getLeft() + arguments.xOffset;
yPos = box.getTop() - arguments.yOffset - img.getHeight();
img.setAbsolutePosition( xPos, yPos );
..
}

I don't know, it just seems like the problem lies somewhere in there, perhaps
an if statement or something. I may be completely off, just a thought. Again,
your assistance is ALWAYS appreciated. Thanks.

From: -==cfSearching==- on
Lumpia wrote:
[i]Essentially, could I not just 2 different yOffsets like so:[/i]

Yes. It should work as long as the values correctly account for the size of
the first image. Using
<cfset variables.yOffset = variables.yOffset + variables.img.getHeight()>

Just makes it more dynamic. If you ever changed the watermark images, the
code would still work without having to change hard coded values.

[i]Regardless of how I modify the code, it still wants to overlap the images.
Correct me if I'm wrong, but it seems like the code within the function
(img.setAbsolutePosition(xPos, yPos)) needs to be adjusted to account if there
are 2 images.[/i]

Yes, you are right in thinking that. However, it is already taken care of by
<cfset variables.yOffset = variables.yOffset + variables.img.getHeight()>.
That code adjusts the yOffset, right before the second call, so it takes into
account the height of the first watermark. Let us say your first watermark has
a height of 40. The result should be the same as if you were to adjusted the
positions manually like this:

<cfset variables.xOffset = 160>
<!--- Draw the first watermark 20pt from the top of the crop box--->
<cfset variables.yOffset = 20>
<cfset insertWatermarkPDF( ..., variables.xOffset, variables.yOffset, ...)>

<cfset variables.xOffset = 160>
<!--- Draw the second watermark 60pt from the top of the crop box--->
<!--- ie yOffset = 20 + 40 (image height) --->
<cfset variables.yOffset = 60>
<cfset insertWatermarkPDF( ..., variables.xOffset, variables.yOffset, ...)>


Try the attached example. Download these (2) sample files from the iText
site. Save them to the same directory as your CFM script. You could use
different files, but this way we know you will get the same results.


http://itext.ugent.be/library/com/lowagie/examples/general/copystamp/ChapterSect
ion.pdf

http://itext.ugent.be/library/com/lowagie/examples/general/copystamp/watermark.j
pg

Run the example then open the file named "ChapterSectionFinal.pdf". You
should see that the second watermark is placed below the first one.



FUNCTION

<cfscript>
// BEGIN WATERMARK SCRIPT
//
// zindex refers to placing the image over or under the content, default is
under
// but if your content has a background, it may obscure the watermark
function insertWatermarkPDF(pdfFileIn, imageFile, pdfFileOut, xOffset,
yOffset, zIndex)
{

var Local = structNew();

Local.success = true;

try
{
// create a PdfReader to read the input file
Local.reader =
javaLoader.create("com.lowagie.text.pdf.PdfReader").init( arguments.pdfFileIn );
Local.totalPages = Local.reader.getNumberOfPages();

// create a PdfStamper to generate the output file
Local.out = javaLoader.create("java.io.FileOutputStream").init(
arguments.pdfFileOut );
Local.stamper =
javaLoader.create("com.lowagie.text.pdf.PdfStamper").init( Local.reader,
Local.out);

// Load the watermark image from the supplied path
Local.img = javaLoader.create("com.lowagie.text.Image").getInstance(
arguments.imageFile );

for ( Local.ii = 1; Local.ii LTE Local.totalPages; Local.ii = Local.ii
+ 1)
{
if ( arguments.zIndex ) {
Local.layer = Local.stamper.getOverContent( javaCast("int",
Local.ii) );
}
else {
Local.layer = Local.stamper.getUnderContent( javaCast("int",
Local.ii) );
}

// get the size of the cropbox
Local.box = Local.reader.getCropBox( javacast("int", Local.ii) );
// calculate the x and y postions based on the given offsets
Local.xPos = Local.box.getLeft() + arguments.xOffset;
Local.yPos = Local.box.getTop() - arguments.yOffset -
Local.img.getHeight();

Writeoutput("DEBUGGING ONLY: page["& Local.ii &"] xPos="&
Local.xPos &", yPos="& Local.yPos &"<br>");

Local.img.setAbsolutePosition( Local.xPos, Local.yPos );
// draw the watermark image
Local.layer.addImage( Local.img );
}

// always close the file and outstream
Local.stamper.close();
Local.out.close();
Local.success = true;
}
catch (any e)
{
if ( structKeyExists(Local, "stamper") ) {
Local.stamper.close();
}
if ( structKeyExists(Local, "out") ) {
Local.out.close();
}
// NOTE - you may wish to rethrow the error here instead
Local.success = false;
}

return Local.success;
}

</cfscript>

EXAMPLE
<!---
Requires these (2) source files exist in the current directory.

http://itext.ugent.be/library/com/lowagie/examples/general/copystamp/ChapterSect
ion.pdf

http://itext.ugent.be/library/com/lowagie/examples/general/copystamp/watermark.j
pg
--->

<cfset form.image1 = "watermark">
<cfset form.image2 = "watermark">

<!--- These must be absolute paths --->
<cfset variables.fullPathToImage1 =
ExpandPath("./#form.image1#.jpg")>
<cfset variables.fullPathToImage2 =
ExpandPath("./#form.image2#.jpg")>
<cfset variables.fullPathToInputFile =
ExpandPath("./ChapterSection.pdf")>
<cfset variables.fullPathToOutputFile1 =
ExpandPath("./ChapterSectionTemp.pdf")>
<cfset variables.fullPathToOutputFile2 =
ExpandPath("./ChapterSectionFinal.pdf")>

<!---
position the first image 160pt from left and 20pt from the top of
cropbox
--->
<cfset variables.xOffset = 160>
<cfset variables.yOffset = 20>

<cfif len(trim(form.image1)) >
<cfset insertWatermarkPDF( fullPathToInputFile
, fullPathToImage1
, fullPathToOutputFile1
, variables.xOffset
, variables.yOffset
, 0
)>
<!---
to place the second image BELOW the first one, we must
add the height of the first image to the yOffset

to place it to the RIGHT of the first one, add the width
to the xoffset
--->
<cfset variables.img =
javaLoader.create("com.lowagie.text.Image").getInstance(
variables.fullPathToImage1 )>
<cfset variables.yOffset = variables.yOffset +
variables.img.getHeight()>

</cfif>

<cfif len(trim(form.image2)) >
<cfset insertWatermarkPDF( fullPathToOutputFile1
, fullPathToImage2
, fullPathToOutputFile2
, variables.xOffset
, variables.yOffset
, 0
)>
</cfif>