/* * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright 2008 jOpenDocument, by ILM Informatique. All rights reserved. * * The contents of this file are subject to the terms of the GNU * General Public License Version 3 only ("GPL"). * You may not use this file except in compliance with the License. * You can obtain a copy of the License at http://www.gnu.org/licenses/gpl-3.0.html * See the License for the specific language governing permissions and limitations under the License. * * When distributing the software, include this License Header Notice in each file. * */ package org.jopendocument.dom.spreadsheet; import org.jopendocument.dom.ODFrame; import org.jopendocument.util.ImageInfo; import org.jopendocument.util.ImageUtils; import java.awt.Color; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.imageio.ImageIO; import org.jdom.Element; abstract class BytesProducer { /** * The data of an image to put in <code>frame</code>. * * @param frame the frame where this image will be put. * @return the corresponding bytes. */ abstract byte[] getBytes(ODFrame<?> frame); /** * The format of the data returned by {@link #getBytes(Element)}. * * @return the name of the format, <code>null</code> if unknown, eg "png". */ abstract String getFormat(); // *** concrete subclasses // a no-op Producer static final class ByteArrayProducer extends BytesProducer { private final byte[] data; private final boolean keepRatio; public ByteArrayProducer(byte[] data) { this(data, false); } public ByteArrayProducer(byte[] data, boolean keepRatio) { super(); this.data = data; this.keepRatio = keepRatio; } @Override public byte[] getBytes(final ODFrame<?> frame) { if (this.keepRatio) { final ImageInfo info = new ImageInfo(); info.setInput(new ByteArrayInputStream(this.data)); if (!info.check()) throw new IllegalStateException("unable to parse the picture"); final double imgRatio = info.getWidth() / (double) info.getHeight(); final double ratio = frame.getRatio(); // svg:x="0.075cm" svg:y="0.343cm" if (imgRatio > ratio) { final double newFrameHeight = frame.getWidth().doubleValue() / imgRatio; final double diff = frame.getHeight().doubleValue() - newFrameHeight; frame.setSVGAttr("y", frame.getY().doubleValue() + diff / 2.0d); frame.setSVGAttr("height", newFrameHeight); } else { final double newFrameWidth = frame.getHeight().doubleValue() * imgRatio; final double diff = frame.getWidth().doubleValue() - newFrameWidth; frame.setSVGAttr("x", frame.getX().doubleValue() + diff / 2.0d); frame.setSVGAttr("width", newFrameWidth); } // table:end-cell-address="Feuille1.F52" table:end-x="2.247cm" table:end-y="0.066cm" final Element frameElem = frame.getElement(); frameElem.removeAttribute("end-cell-address", frameElem.getNamespace("table")); frameElem.removeAttribute("end-x", frameElem.getNamespace("table")); frameElem.removeAttribute("end-y", frameElem.getNamespace("table")); } return this.data; } @Override public String getFormat() { return null; } } // will generate a new png image (and can also keep ratio) static final class ImageProducer extends BytesProducer { private final Image img; private final boolean keepRatio; public ImageProducer(Image img, boolean keepRatio) { super(); this.img = img; this.keepRatio = keepRatio; } @Override public byte[] getBytes(final ODFrame<?> frame) { final BufferedImage bImg; if (this.keepRatio) { final float ratio = (float) frame.getRatio(); bImg = ImageUtils.createQualityResizedImage(this.img, ratio, true, Color.WHITE, true); } else bImg = ImageUtils.createQualityResizedImage(this.img, this.img.getWidth(null), this.img.getHeight(null), true, true, Color.WHITE, true); final ByteArrayOutputStream out = new ByteArrayOutputStream(1024 * 1024); try { ImageIO.write(bImg, getFormat(), out); } catch (IOException e) { throw new IllegalStateException("unable to export " + bImg + " to " + getFormat()); } return out.toByteArray(); } @Override public String getFormat() { return "png"; } } }