/** * * Copyright (c) 2009-2016 Freedomotic team http://freedomotic.com * * This file is part of Freedomotic * * 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 2, 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 * Freedomotic; see the file COPYING. If not, see * <http://www.gnu.org/licenses/>. */ package com.freedomotic.core; import com.freedomotic.app.Freedomotic; import com.freedomotic.settings.Info; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import java.awt.AlphaComposite; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.imageio.ImageIO; /** * * @author Enrico Nicoletti */ public final class ResourcesManager { private static final Logger LOG = LoggerFactory.getLogger(ResourcesManager.class.getName()); private static final LoadingCache<String, BufferedImage> imagesCache = CacheBuilder.newBuilder() .expireAfterAccess(1, TimeUnit.MINUTES) .weakValues() .build(new CacheLoader<String, BufferedImage>() { @Override public BufferedImage load(String imageName) throws Exception { //loads image from disk searching it recursively in a given folder BufferedImage img = fetchFromHDD(Info.PATHS.PATH_RESOURCES_FOLDER, imageName); if (img != null) { return img; } else { throw new IOException("Cannot recursively find image " + imageName + " in " + Info.PATHS.PATH_RESOURCES_FOLDER); } } }); /** * * @param imageName * @param width * @param height * @return */ public static BufferedImage getResource(String imageName, int width, int height) { try { // Resizeing not needed, return standard image if ((width <= 0) || (height <= 0)) { return imagesCache.get(imageName); } // Compute the resized image key String resizedImageName = imageName + "_" + width + "x" + height; BufferedImage img = imagesCache.getIfPresent(resizedImageName.toLowerCase()); // Resized image is in cache if (img != null) { return img; } else { //get the unresized image from cache or disk try { img = imagesCache.get(imageName); } catch (ExecutionException e) { try { File imageFile = new File(imageName); if (imageFile.exists()) { img = ImageIO.read(imageFile); imagesCache.put(imageFile.getName(), img); } else { return null; } } catch (IOException er) { LOG.error(Freedomotic.getStackTraceInfo(er)); return null; } } // Resize and cache if (img.getWidth() != width && img.getHeight() != height) { img = resizeImage(img, width, height); } imagesCache.put(resizedImageName.toLowerCase(), img); return img; } } catch (ExecutionException ex) { LOG.error(ex.getMessage()); return null; } } /** * * @param imageName * @return */ public static synchronized BufferedImage getResource(String imageName) { try { return imagesCache.get(imageName); } catch (ExecutionException ex) { LOG.error(ex.getMessage()); return null; } } /** * * @param folder * @param fileName * @return */ public static File getFile(File folder, String fileName) { DirectoryReader dirReader = new DirectoryReader(); dirReader.find(folder, fileName); return dirReader.getFile(); } /** * * @param imageName * @param image */ public static synchronized void addResource(String imageName, BufferedImage image) { imagesCache.put(imageName, image); } /** * Removes any cached element. * */ public static void clear() { imagesCache.cleanUp(); } private static BufferedImage resizeImage(BufferedImage image, int width, int height) { int type = image.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : image.getType(); BufferedImage resizedImage = new BufferedImage(width, height, type); Graphics2D tmp = resizedImage.createGraphics(); tmp.setComposite(AlphaComposite.Src); tmp.drawImage(image, 0, 0, width, height, null); return resizedImage; } /** * * * @param folder * @param imageName * @return * @throws IOException */ private static BufferedImage fetchFromHDD(File folder, String imageName) throws IOException { BufferedImage img = null; try { DirectoryReader dirReader = new DirectoryReader(); dirReader.find(folder, imageName); File file = dirReader.getFile(); if (file != null) { img = ImageIO.read(file); } } catch (IOException ex) { throw new IOException(); } return img; } /** * */ private static class DirectoryReader { private File output = null; private void find(File folder, String fileName) { if (folder.isFile()) { if (folder.getName().equalsIgnoreCase(fileName)) { output = folder; //the fileName is found } } else if (folder.isDirectory()) { //a subdirectory File[] listOfFiles = folder.listFiles(); if (listOfFiles != null) { for (int i = 0; i < listOfFiles.length; i++) { find(listOfFiles[i], fileName); } } } } /** * * * @return */ public File getFile() { return output; } } private ResourcesManager() { } }