package utility; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import javax.imageio.ImageIO; import javax.swing.JLabel; /** * * @author TU-Darmstadt BP Gruppe 7 WS17/18 * Centralized resource loading methods * for improved performance and easier troubleshooting. */ public class ImageImport { /** * 30x30 pixel FileNotFound Icon, which can be shown without using I/O operations * a red cross. */ static private BufferedImage defaultImage; /* * Save nothing: Reload every image whenever requested. * Save external: Only save images that were found as external file. * Save raw: Save all non-scaled images. * Save everything: self-explanatory. */ private static final byte SAVE_NOTHING=0, /*SAVE_EXTERNAL=1,*/ SAVE_RAW=2, SAVE_EVERYTHING=4, SAVE_MODE=SAVE_EVERYTHING; private static HashMap imgStorage; private static ImageImport xmp=new ImageImport();//Used to load resources from the JAR. static{ /* * creates the default Image */ defaultImage = new BufferedImage(30,30,BufferedImage.TYPE_BYTE_INDEXED); for(int x = 0; x < 30; x++) for(int y = 0; y < 30; y++){ if(x == 29 || y == 29) //Border Bottom/Left -> Light Grey (defaultImage).setRGB(x, y, 13158600); else if(x == 0 || y == 0) //Border Top/Right -> Dark Grey (defaultImage).setRGB(x, y, 6316128); else if((x == y || x == 31 - y) && 6 < x && x < 25) //Red Cross in the middle (defaultImage).setRGB(x, y, 13107200); else //all other Pixels are white (defaultImage).setRGB(x, y, 16777215); } if(SAVE_MODE!=SAVE_NOTHING)imgStorage=new HashMap(); } /** * The rawest function replacing the old method without any default parameters. * Currently not used in HOLEG at all(aside form calls from the convenience methods). * @param url Path to the image to be loaded. * @param w Width the loaded image should be scaled to. * @param h Height the loaded image should be scaled to. * @param hints Hints for the scaling algorithm to be used. * Same as the parameter in the getScaledInstance function of Image. * @return A loaded and scaled image from the requested path. */ static Image loadImage(String url, int w, int h, int hints){ if(SAVE_MODE==SAVE_EVERYTHING){ String key=url+"?"+w+"?"+h+"?"+hints; if(imgStorage.containsKey(key))return(imgStorage.get(key)); else{ Image img=loadImage(url).getScaledInstance(w, h, hints); imgStorage.put(key, img); return img; } } return loadImage(url).getScaledInstance(w, h, hints); } /** * Loads an image from the given path and scales it using the smooth algorithm. * @param url Path to the image to be loaded. * @param w Width the loaded image should be scaled to. * @param h Height the loaded image should be scaled to. * @return A loaded and (smoothly) scaled image from the requested path. */ public static Image loadImage(String url, int w, int h){ return loadImage(url,w,h, Image.SCALE_SMOOTH); } /** * Loads an image from the given path and scales it using the smooth algorithm. * @param url Path to the image to be loaded. * @param w Width the loaded image should be scaled to. * @param h Height the loaded image should be scaled to. * @return An image loaded from the requested path. */ public static Image loadImage(String url){ if(SAVE_MODE!=SAVE_NOTHING){ if(imgStorage.containsKey(url))return imgStorage.get(url); else{ Image img; try { img= ImageIO.read(loadStream(url)); } catch (IOException e) { e.printStackTrace(); return defaultImage; } imgStorage.put(url, img); return img; } } try { return ImageIO.read(loadStream(url)); } catch (IOException e) { e.printStackTrace(); return defaultImage; } } /** * Loads any resource with a given path, * regardless of whether it is inside the jar or an external resource. * Every loadImage() function uses this as a basis. * @param url The path (and file name) of the requested resource. * @return An InputStream from the requested resource. */ public static InputStream loadStream(String url){ InputStream o=xmp.getClass().getResourceAsStream(url); if(o!=null)return o; else{ boolean rootSymbol=false; //Whether url starts with a / or \ switch(url.charAt(0)){ //So we can make sure to construct res/path correctly. case '/':case '\\':rootSymbol=true; } try { //Mixed separators might cause problems. Will fix later. File f=new File(url);//Possible bug with duplicate names. if(!f.exists())url="res"+(rootSymbol?"":"/")+url; return new FileInputStream(url); } catch (FileNotFoundException e1) { e1.printStackTrace(); } return null; } } //Nobody needs an instance of this. I do, because I use it to load images from inside the JAR. private ImageImport(){} }