/* * Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved. * * This file is part of the Jspresso framework. * * Jspresso is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Jspresso 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Jspresso. If not, see <http://www.gnu.org/licenses/>. */ package org.jspresso.framework.util.image; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.nio.charset.StandardCharsets; import javaxt.io.Image; import org.apache.commons.codec.binary.Base64; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.jspresso.framework.util.io.IoHelper; import org.jspresso.framework.util.url.UrlHelper; /** * This is a simple helper class to be able to deal with images. * * @author Vincent Vandenschrick */ public final class ImageHelper { private final static Logger LOG = LoggerFactory.getLogger(ImageHelper.class); /** * The constant SVG is "svg". */ public static final String SVG = "svg"; /** * The constant SVG_CONTENT_TYPE is "image/svg+xml". */ public static final String SVG_CONTENT_TYPE = "image/svg+xml"; /** * The constant PNG is "png". */ public static final String PNG = "png"; private ImageHelper() { // private constructor for helper class. } /** * Scale image. * * @param originalImageInput * the original image input. * @param width * the width * @param height * the height * @param targetFormatName * the format name. * @return the buffered input stream * * @throws IOException * the iO exception */ public static byte[] scaleImage(Object originalImageInput, Integer width, Integer height, String targetFormatName) throws IOException { if (SVG.equals(targetFormatName)) { String svgImage = createSvgImage(originalImageInput); if (width != null) { svgImage = svgImage.replaceFirst("width\\s*=\\s*\"\\d*\"", "width=\"" + width + "\""); } if (height != null) { svgImage = svgImage.replaceFirst("height\\s*=\\s*\"\\d*\"", "height=\"" + height + "\""); } return svgImage.getBytes(StandardCharsets.UTF_8); } else { byte[] imageBytes = extractImageBytes(originalImageInput); Image image; try { image = new Image(imageBytes); } catch (Throwable ex) { if (originalImageInput instanceof byte[]) { LOG.warn("Received an invalid image content. Cannot transform so returning original content.", ex); return (byte[]) originalImageInput; } LOG.warn("Received an invalid image content. Cannot transform so returning null.", ex); return null; } try { image.rotate(); } catch (Throwable ex) { LOG.warn("Cannot rotate the image so leaving it as is.", ex); } try { int originalWidth = image.getWidth(); int originalHeight = image.getHeight(); if (width != null && height != null && width != originalWidth && height != originalHeight) { image.resize(width, height, true); } else if (height == null && width != null && width != originalWidth) { image.setWidth(width); } else if (width == null && height != null && height != originalHeight) { image.setHeight(height); } else { return imageBytes; } } catch(Throwable ex) { LOG.warn("Cannot resize the image so leaving it as is.", ex); } if (targetFormatName != null) { return image.getByteArray(targetFormatName); } return image.getByteArray("PNG"); } } /** * Scale image. * * @param originalImageInput * the original image input. * @param width * the width * @param height * the height * @return the buffered input stream * * @throws IOException * the iO exception */ public static byte[] scaleImage(Object originalImageInput, Integer width, Integer height) throws IOException { return scaleImage(originalImageInput, width, height, null); } /** * Create image. * * @param originalImageInput * the original image input * @return the image * * @throws IOException * the iO exception */ public static byte[] extractImageBytes(Object originalImageInput) throws IOException { byte[] imageBytes; if (originalImageInput instanceof byte[]) { imageBytes = (byte[]) originalImageInput; } else { ByteArrayOutputStream baos = new ByteArrayOutputStream(); if (originalImageInput instanceof String) { IoHelper.copyStream(UrlHelper.createURL((String) originalImageInput).openStream(), baos); } else if (originalImageInput instanceof URL) { IoHelper.copyStream(((URL) originalImageInput).openStream(), baos); } else if (originalImageInput instanceof InputStream) { IoHelper.copyStream((InputStream) originalImageInput, baos); } else { throw new RuntimeException("Unsupported image input."); } imageBytes = baos.toByteArray(); } return imageBytes; } /** * Create SVG image. * * @param originalImageInput * the original image input * @return the SVG image * * @throws IOException * the iO exception */ public static String createSvgImage(Object originalImageInput) throws IOException { InputStream svgInputStream; if (originalImageInput instanceof byte[]) { svgInputStream = new ByteArrayInputStream((byte[]) originalImageInput); } else if (originalImageInput instanceof String) { try { svgInputStream = UrlHelper.createURL((String) originalImageInput).openStream(); } catch(IOException ioe) { svgInputStream = new ByteArrayInputStream(((String) originalImageInput).getBytes(StandardCharsets.UTF_8)); } } else if (originalImageInput instanceof URL) { svgInputStream = ((URL) originalImageInput).openStream(); } else if (originalImageInput instanceof InputStream) { svgInputStream = (InputStream) originalImageInput; } else { throw new RuntimeException("Unsupported SVG image input."); } ByteArrayOutputStream svgOutputStream = new ByteArrayOutputStream(); try { IoHelper.copyStream(svgInputStream, svgOutputStream); return svgOutputStream.toString(StandardCharsets.UTF_8.name()); } finally { if (svgInputStream != null) { svgInputStream.close(); } svgOutputStream.close(); } } /** * To base 64 src. * * @param originalImageInput * the original image input * @param format * the format * @return the string * * @throws IOException * the iO exception */ public static String toBase64Src(Object originalImageInput, String format) throws IOException { Image img = new Image(extractImageBytes(originalImageInput)); return "data:image/" + format + ";base64," + Base64.encodeBase64String(img.getByteArray(format)); } /** * From base 64 src. * * @param base64Src * the base 64 src * @return the byte [ ] */ public static byte[] fromBase64Src(String base64Src) { return Base64.decodeBase64(base64Src.replaceAll("^.*base64,", "")); } /** * Load image from project's resource path. * @param resourcePath The path to the resource. * @return the image as bytes. * @throws IOException If resource cannot be read. */ public static byte[] loadImage(String resourcePath) throws IOException { if (!resourcePath.startsWith("/")) { resourcePath = "/" + resourcePath; } try (InputStream is =ImageHelper.class.getResourceAsStream(resourcePath)){ return extractImageBytes(is); } } }