Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright (C) 2011-2015 The XDocReport Team
*
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
package fr.opensagres.odfdom.converter.pdf.internal;
import java.io.ByteArrayOutputStream;
import com.lowagie.text.Image;
import com.lowagie.text.pdf.PdfContentByte;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
/**
* A pojo containing all the information of a background image.
*/
public class BackgroundImage {
private static final int DEFAULT_DPI = 72;
private final byte[] imageBytes;
private final Repeat repeat;
private final Float pageWidth;
private final Float pageHeight;
private final Position position;
private final Float leftMargin;
private final Float rightMargin;
private final Float topMargin;
private final Float bottomMargin;
/**
* A type of background image.
*/
public static enum Repeat {
STRETCH("stretch"),
NONE("no-repeat"),
BOTH("repeat");
private String odtValue;
private Repeat(String odtValue) {
this.odtValue = odtValue;
}
/**
* Returns the correct {@link Repeat} for a image.
* @param str the string containing the ODF repeat value.
* @return the correct Repeat
* @exception IllegalArgumentException when the value is not defined
*/
public static Repeat fromODT(String str) {
for (Repeat repeat : Repeat.values()) {
if (repeat.odtValue.equals(str)) return repeat;
}
throw new IllegalArgumentException(str + " odt value not recognized.");
}
}
/**
* The position of a background image.
*/
public static enum Position {
TOP_LEFT("top left"),
TOP_CENTER("top center"),
TOP_RIGHT("top right"),
CENTER_LEFT("center left"),
CENTER_CENTER("center center", "center"),
CENTER_RIGHT("center right"),
BOTTOM_LEFT("bottom left"),
BOTTOM_CENTER("bottom center"),
BOTTOM_RIGHT("bottom right");
private String[] odtValues;
private Position(String... odtValues) {
this.odtValues = odtValues;
}
/**
* Returns the correct {@link Position} for a image.
* @param str the string containing the ODF repeat value.
* @return the correct Position
* @exception IllegalArgumentException when the value is not defined
*/
public static Position fromODT(String str) {
for (Position position : Position.values()) {
for (String odtValue : position.odtValues) if (odtValue.equals(str)) return position;
}
throw new IllegalArgumentException(str + " odt value not recognized.");
}
}
/**
* The builder class for a {@link BackgroundImage}.
*/
public static class Builder {
private final byte[] bytes;
private Float pageWidth;
private Float pageHeight;
private Repeat repeat;
private Position position;
private Float leftMargin;
private Float rightMargin;
private Float topMargin;
private Float bottomMargin;
public Builder(byte[] image) {
this.bytes = image;
}
public Builder setPageWidth(float width) {
this.pageWidth = width;
return this;
}
public Builder setPageHeight(float height) {
this.pageHeight = height;
return this;
}
public Builder setRepeat(Repeat repeat) {
this.repeat = repeat;
return this;
}
public Builder setPosition(Position position) {
this.position = position;
return this;
}
public Builder setLeftMargin(Float margin) {
this.leftMargin = margin;
return this;
}
public Builder setRightMargin(Float margin) {
this.rightMargin = margin;
return this;
}
public Builder setTopMargin(Float margin) {
this.topMargin = margin;
return this;
}
public Builder setBottomMargin(Float margin) {
this.bottomMargin = margin;
return this;
}
public BackgroundImage build() {
return new BackgroundImage(this);
}
}
private BackgroundImage(Builder builder) {
this.imageBytes = builder.bytes;
this.repeat = builder.repeat;
this.pageWidth = builder.pageWidth;
this.pageHeight = builder.pageHeight;
this.position = builder.position;
this.leftMargin = builder.leftMargin;
this.rightMargin = builder.rightMargin;
this.topMargin = builder.topMargin;
this.bottomMargin = builder.bottomMargin;
}
/**
* Insert the backgroundImage in the given OutputStream.
* @param out the pdf as a ByteArrayOutputStream
*/
public ByteArrayOutputStream insert(ByteArrayOutputStream out) {
try {
Image image = Image.getInstance(imageBytes);
float imageWidth = image.getWidth() * DEFAULT_DPI / image.getDpiX();
float imageHeight = image.getHeight() * DEFAULT_DPI / image.getDpiY();
switch (repeat) {
case BOTH:
ByteArrayOutputStream stream = out;
//TODO: maybe we could get better results if we tiled the byteArray instead of the images themselves.
for (float x = leftMargin; x < pageWidth - rightMargin; x += imageWidth) {
for (float y = pageHeight - topMargin; y > bottomMargin; y -= imageHeight) {
if (x + imageWidth > pageWidth - rightMargin || y - imageHeight < bottomMargin) {
byte[] data = new byte[(int)imageWidth * (int)imageHeight];
for (int k = 0; k < (int)imageHeight; k++) {
for (int i = 0; i < imageWidth; i++) {
if (x + i < pageWidth - rightMargin && y - k > bottomMargin) {
data[i + k * (int)imageWidth] = (byte) 0xff;
}
}
}
Image clone = Image.getInstance(image);
Image mask = Image.getInstance((int)imageWidth, (int)imageHeight, 1, 8, data);
mask.makeMask();
clone.setImageMask(mask);
clone.setAbsolutePosition(x, y - imageHeight);
stream = insertImage(stream, clone);
} else {
image.setAbsolutePosition(x, y - imageHeight);
image.scaleAbsolute(imageWidth, imageHeight);
stream = insertImage(stream, image);
}
}
}
return stream;
case NONE:
float y;
if (position.name().split("_")[0].equals("TOP")) {
y = pageHeight - imageHeight - topMargin;
} else if (position.name().split("_")[0].equals("CENTER")) {
y = (pageHeight - imageHeight - topMargin) / 2;
} else if (position.name().split("_")[0].equals("BOTTOM")) {
y = bottomMargin;
} else {
throw new UnsupportedOperationException(position + " is not supported");
}
float x;
if (position.name().split("_")[1].equals("LEFT")) {
x = leftMargin;
} else if (position.name().split("_")[1].equals("CENTER")) {
x = (pageWidth - imageWidth - rightMargin) / 2;
} else if (position.name().split("_")[1].equals("RIGHT")) {
x = pageWidth - imageWidth - rightMargin;
} else {
throw new UnsupportedOperationException(position + " is not supported");
}
image.setAbsolutePosition(x, y);
image.scaleAbsolute(imageWidth, imageHeight);
return insertImage(out, image);
case STRETCH:
image.setAbsolutePosition(leftMargin, bottomMargin);
image.scaleAbsolute(pageWidth - leftMargin - rightMargin, pageHeight - topMargin - bottomMargin);
return insertImage(out, image);
default:
throw new UnsupportedOperationException(repeat + " is not implemented");
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private ByteArrayOutputStream insertImage(ByteArrayOutputStream out, Image image) {
try {
ByteArrayOutputStream os = new ByteArrayOutputStream(out.size());
PdfReader reader = new PdfReader(out.toByteArray());
PdfStamper stamper = new PdfStamper(reader, os);
for (int i = 1; i <= reader.getNumberOfPages(); i++) {
PdfContentByte canvas = stamper.getUnderContent(i);
canvas.addImage(image);
}
reader.close();
stamper.close();
return os;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}