/* ===================================================================== * OrsonPDF : a fast, light-weight PDF library for the Java(tm) platform * ===================================================================== * * (C)opyright 2013-2015, by Object Refinery Limited. All rights reserved. * * Project Info: http://www.object-refinery.com/orsonpdf/index.html * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. * Other names may be trademarks of their respective owners.] * * If you do not wish to be bound by the terms of the GPL, an alternative * commercial license can be purchased. For details, please see visit the * Orson PDF home page: * * http://www.object-refinery.com/orsonpdf/index.html * */ package com.orsonpdf; import com.orsonpdf.util.Args; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.image.BufferedImage; /** * Represents an image in a PDF document. */ public class PDFImage extends Stream { /** The width. */ int width; /** The height. */ int height; /** The image. */ Image image; String softMaskImageRef; /** * Creates a new image object. * * @param number the PDF object number. * @param img the AWT image object ({@code null} not permitted). * @param softMaskImageRef the soft mask image reference ({@code null} * permitted). */ public PDFImage(int number, Image img, String softMaskImageRef) { super(number); Args.nullNotPermitted(img, "img"); this.width = img.getWidth(null); this.height = img.getHeight(null); this.image = img; this.softMaskImageRef = softMaskImageRef; } /** * Returns the raw image data. Each call will resample the image data * and populate a new array. Note that the stream may encode this * data before it is written to the PDF output. * * @return The raw stream data. */ @Override public byte[] getRawStreamData() { BufferedImage bi; if (!(this.image instanceof BufferedImage)) { bi = new BufferedImage(this.width, this.height, BufferedImage.TYPE_INT_ARGB); Graphics2D g2 = bi.createGraphics(); g2.setBackground(new Color(255, 255, 255, 0)); g2.clearRect(0, 0, this.width, this.height); g2.drawImage(this.image, 0, 0, null); } else { bi = (BufferedImage) this.image; } // create a byte array of the image data to go in the PDF byte[] result = new byte[this.width * this.height * 3]; int i = 0; for (int hh = this.height - 1; hh >= 0; hh--) { for (int ww = 0; ww < this.width; ww++) { int rgb = bi.getRGB(ww, hh); result[i++] = (byte) (rgb >> 16); result[i++] = (byte) (rgb >> 8); result[i++] = (byte) rgb; } } return result; } /** * Creates a dictionary reflecting the current configuration for this * image. * * @param streamLength the stream length. * * @return A dictionary. */ @Override protected Dictionary createDictionary(int streamLength) { Dictionary dictionary = super.createDictionary(streamLength); dictionary.setType("/XObject"); dictionary.put("/Subtype", "/Image"); dictionary.put("/ColorSpace", "/DeviceRGB"); dictionary.put("/BitsPerComponent", 8); dictionary.put("/Width", this.width); dictionary.put("/Height", this.height); if (this.softMaskImageRef != null) { dictionary.put("/SMask", this.softMaskImageRef); } return dictionary; } }