package org.ff4j.web.console; /* * #%L * ff4j-web * %% * Copyright (C) 2013 - 2016 FF4J * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * #L% */ import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.Map; import javax.imageio.ImageIO; import javax.xml.bind.DatatypeConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.thymeleaf.context.WebContext; /** * Load image as base64 and store them in cache * * @author Cedrick LUNVEN (@clunven) */ public class ImageProvider { /** Logger for this class. */ private static final Logger LOGGER = LoggerFactory.getLogger(ImageProvider.class); /** Expected format. */ public static enum ImageType { png, jpg, jpeg }; /** Eternal cache for images. */ private Map < String, String > loadedImages = new HashMap< String, String >(); /** Singleton. */ private static ImageProvider _instance = null; /** Hide constructor. */ private ImageProvider() { } /** * Singleton. * * @return * pattern singleton */ public static synchronized ImageProvider getInstance() { if (_instance == null) { _instance = new ImageProvider(); } return _instance; } /** * Transform inputStream into base64. * * @param image The image to encode * @param type jpeg, bmp, ... * @return encoded string */ private String fromFileToBase64(InputStream is, ImageType type) { ByteArrayOutputStream bos = new ByteArrayOutputStream(); try { // Reading BufferedImage image = ImageIO.read(is); // Resizing BufferedImage resizedImage = new BufferedImage(130, 180, image.getType()); Graphics2D g = resizedImage.createGraphics(); g.drawImage(image, 0, 0, 130, 180, null); g.dispose(); // Write into outpustream ImageIO.write(resizedImage, type.toString(), bos); // Convert to base64 return DatatypeConverter.printBase64Binary(bos.toByteArray()); } catch (IOException e) { throw new IllegalArgumentException("Cannot convert image to base64", e); } finally { try { bos.close(); } catch (IOException e) {} } } /** * Load resource from fileSystem. * * @param imageName * target image name * @param type * target image extension * @return * image as base64 and in the cache */ private String getImage(String imageName, ImageType type) { if (!loadedImages.containsKey(imageName)) { InputStream is = getClass().getClassLoader().getResourceAsStream("static/img/" + imageName + "." + type); if (is != null) { loadedImages.put(imageName, fromFileToBase64(is, type)); } else { LOGGER.warn("File [" + imageName + "." + type + "] has not been found"); } } return loadedImages.get(imageName); } /** * Public interface to add images to webcontext for rendering. * * @param ctx * thymeleaf context * @param imageName * current image name * @param type * current image type */ public void addImageToContext(WebContext ctx, String imageName, ImageType type) { String base64 = getImage(imageName, type); if (base64 != null) { ctx.setVariable("flagFrance", "data:image/jpg;base64," + base64); } } }