Меня этот вариант не устраивает абсолютно к сожалению. 1. один раз создав такой слой невозможно его будет потом изменить (например если изменится водяной знак) 2. при печати слой можно при желании включить самостоятельно 3. усложняется проверка на водяной знак Вот как выглядит мое решение на данный момент: Код | package de.inplus.umsys.web.observer.tools;
import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Map; import java.util.Set;
import org.springframework.beans.factory.annotation.Required; import org.springframework.core.io.Resource;
import com.itextpdf.text.Image; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PRStream; import com.itextpdf.text.pdf.PdfArray; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfDictionary; import com.itextpdf.text.pdf.PdfGState; import com.itextpdf.text.pdf.PdfLayer; import com.itextpdf.text.pdf.PdfName; import com.itextpdf.text.pdf.PdfNumber; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.PdfWriter;
public class WatermarkTool {
private Resource watermark;
public void setWatermarkRight(File document, boolean shouldBeMarked) throws Exception { try { byte[] buffer = new byte[(int) document.length()]; InputStream in = new FileInputStream(document); in.read(buffer); in.close(); PdfReader reader = new PdfReader(buffer); PdfDictionary pageDict; int n = reader.getNumberOfPages(); PdfStamper stamper = new PdfStamper(reader, new FileOutputStream( document)); Map<String, PdfLayer> layers = stamper.getPdfLayers(); boolean wm = false; if (!layers.isEmpty()) { Set<String> keys = layers.keySet(); for (String key : keys) { if (key.toString().equalsIgnoreCase("watermark")) wm = true; } } if ((shouldBeMarked==true)&&(wm==false)) { addWatermarkLayer(reader, stamper); } if((shouldBeMarked ==false)&&(wm==true)) { removeWatermark(reader, stamper); } stamper.close();
} catch (Exception e) { throw e; } finally { } }
private void addWatermarkLayer(PdfReader reader, PdfStamper stamper) throws Exception { Image watermarkImage = Image.getInstance(watermark.getFile().getPath()); PdfLayer wmLayer = new PdfLayer("watermark", stamper.getWriter()); wmLayer.setOnPanel(true); // set layer parameters wmLayer.setPrint("print", true); wmLayer.setOn(true); wmLayer.setView(true); // Prepare transperancy PdfGState transparent = new PdfGState(); transparent.setStrokeOpacity(0.4f); transparent.setFillOpacity(0.4f); PdfContentByte cb; int toPage = stamper.getReader().getNumberOfPages(); for (int i = 1; i <= toPage; i++) {
cb = stamper.getUnderContent(i);
Rectangle rectangle = stamper.getReader() .getPageSizeWithRotation(i);
cb.beginLayer(wmLayer); cb.setGState(transparent); // set block trasparency properties
// position relative to top watermarkImage.scaleAbsoluteHeight(rectangle.getHeight() - 20); watermarkImage.scaleAbsoluteWidth(rectangle.getWidth() - 20); float absoluteY = rectangle.getBottom() + (rectangle.getHeight() - watermarkImage.getPlainHeight() - 10); watermarkImage.setAbsolutePosition(10, 10); cb.addImage(watermarkImage); cb.endLayer();
} }
public void removeWatermark(PdfReader reader, PdfStamper stamper){
try { PdfDictionary root = reader.getCatalog(); root.remove(PdfName.OCPROPERTIES); PdfDictionary page; PdfArray contentarray; PRStream stream; String content; PdfDictionary resources; PdfDictionary xobjects; for (int i = 0; i < reader.getNumberOfPages(); i++) { page = reader.getPageN(1); contentarray = page.getAsArray(PdfName.CONTENTS); if (contentarray != null) { for (int j = 0; j < contentarray.size(); j++) { stream = (PRStream) contentarray.getAsStream(j); content = new String(PdfReader.getStreamBytes(stream)); if (content.indexOf("/OC") > 0) { stream.put(PdfName.LENGTH, new PdfNumber(0)); stream.setData(new byte[0]); } } } resources = page.getAsDict(PdfName.RESOURCES); xobjects = resources.getAsDict(PdfName.XOBJECT); for (PdfName name : xobjects.getKeys()) { stream = (PRStream) xobjects.getAsStream(name); if (stream.get(PdfName.OC) == null) { continue; } stream.put(PdfName.LENGTH, new PdfNumber(0)); stream.setData(new byte[0]); } }
stamper.setViewerPreferences(PdfWriter.PageModeUseNone); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public Resource getWatermark() { return watermark; }
@Required public void setWatermark(Resource watermark) { this.watermark = watermark; }
}
|
Это уже близко к решению. уберается содержимое уровня но не сам уровень. как это сделать? подозреваю что надо удалить какойто элемент PdfDictionary но не знаю какой. Это сообщение отредактировал(а) azz - 16.6.2011, 18:01
|