View Javadoc

1   package com.melloware.jukes.file.image;
2   
3   import java.awt.Graphics2D;
4   import java.awt.Image;
5   import java.awt.MediaTracker;
6   import java.awt.image.BufferedImage;
7   import java.io.File;
8   import java.io.IOException;
9   import java.net.MalformedURLException;
10  import java.net.URL;
11  import java.util.Locale;
12  
13  import javax.imageio.ImageIO;
14  import javax.swing.ImageIcon;
15  
16  import org.apache.commons.lang.StringUtils;
17  import org.apache.commons.lang.SystemUtils;
18  import org.apache.commons.logging.Log;
19  import org.apache.commons.logging.LogFactory;
20  
21  import com.jgoodies.uif.util.ResourceUtils;
22  import com.melloware.jukes.file.FileUtil;
23  import com.melloware.jukes.file.filter.ImageFilter;
24  import com.melloware.jukes.gui.tool.Settings;
25  
26  /**
27   * Class to represent and storage area for all icon references. This will reduce
28   * overhead and memory usage throughout the application. Also contains some
29   * static helper methods for loading and scaling images.
30   * <p>
31   * <p>
32   * Copyright: Copyright (c) 2006
33   * </p>
34   * <p>
35   * Company: Melloware, Inc.
36   * </p>
37   * @author Emil A. Lefkof III
38   * @version 4.0
39   */
40  public final class ImageFactory {
41  
42     private static final Log LOG = LogFactory.getLog(ImageFactory.class); // AZ
43  
44     public static final ImageIcon ICO_TRAYICON;
45     public static final ImageIcon ICO_TRAYPLAY;
46     public static final ImageIcon ICO_TRAYPAUSE;
47     public static final ImageIcon ICO_TRAYSTOP;
48     public static final ImageIcon IMAGE_NOCOVER;
49  
50     /** EAL **/
51     public static Settings settings = null;
52  
53     /** EAL **/
54     // call this method only once to store the static settings variable from the
55     // MainModule code where its set
56     public static void setSettings(Settings aSettings) {
57        settings = aSettings;
58     }
59  
60     static {
61        if (SystemUtils.IS_OS_WINDOWS) {
62           ICO_TRAYICON = getIcon("images/trayicon.png");
63           ICO_TRAYPLAY = getIcon("images/trayplay.png");
64           ICO_TRAYPAUSE = getIcon("images/traypause.png");
65           ICO_TRAYSTOP = getIcon("images/traystop.png");
66        } else {
67           ICO_TRAYICON = getIcon("images/tray_icon_24x24.png");
68           ICO_TRAYPLAY = getIcon("images/tray_play_24x24.png");
69           ICO_TRAYPAUSE = getIcon("images/tray_pause_24x24.png");
70           ICO_TRAYSTOP = getIcon("images/tray_stop_24x24.png");
71        }
72  
73        IMAGE_NOCOVER = getIcon("images/image_nocover.jpg");
74     }
75  
76     /**
77      * Default constructor. Private so no instantiation.
78      */
79     private ImageFactory() {
80        super();
81     }
82  
83     /**
84      * Gets the disc and returns it the correct size.
85      * <p>
86      * @param aFileName the file location of the disc
87      * @return the ImageIcon
88      */
89     public static ImageIcon getDiscImage(final String aFileName) {
90        // return getScaledImage(aFileName, 300, 300);
91        // AZ - use settings instead of fixed size
92        return getScaledImage(aFileName, settings.getCoverSizeLarge(), settings.getCoverSizeLarge());
93     }
94  
95     /**
96      * Method to create a new ImageIcon and return the reference
97      * <p>
98      * @param aFileName filename of icon to load
99      * @return ImageIcon reference of fileName
100     */
101    public static ImageIcon getIconFromFile(final String aFileName) {
102       return new ImageIcon(aFileName);
103    }
104 
105    /**
106     * Gets an Image from the URL specified. Safe so we return NULL if anything
107     * goes wrong and the image can not be loaded.
108     * <p>
109     * @param aUrl the URL to look for the image
110     * @return the Image if found, NULL if nothing found
111     */
112    public static Image getImageFromUrl(final String aUrl) {
113       Image image = null;
114       if (StringUtils.isBlank(aUrl)) {
115          throw new IllegalArgumentException("aUrl must be specified");
116       }
117 
118       try {
119          final URL url = new URL(aUrl);
120          image = ImageIO.read(url);
121       } catch (MalformedURLException ex) {
122          image = null;
123       } catch (IOException ex) {
124          image = null;
125       }
126       return image;
127    }
128 
129    /**
130     * Gets an ImageIcon and scales it to the size requested.
131     * <p>
132     * @param aFileName the filename to get
133     * @param height the desired height of the image
134     * @param width the desired width of the image
135     * @return the ImageIcon
136     */
137    public static ImageIcon getScaledImage(final String aFileName, final int height, final int width) {
138       ImageIcon icon = null;
139       final String errorString = ResourceUtils.getString("messages.ErrorReadingImageFile") + ": " + aFileName;
140       if (StringUtils.isBlank(aFileName)) {
141          icon = IMAGE_NOCOVER;
142       } else {
143          // get the image
144          /** AZ **/
145          try {
146             icon = new ImageIcon(aFileName);
147          } catch (Exception ex) {
148             LOG.error(errorString, ex);
149          }
150       }
151 
152       // if no image was found return the default
153       if (MediaTracker.ERRORED == icon.getImageLoadStatus()) {
154          icon = IMAGE_NOCOVER;
155       }
156 
157       // resizing Image Icon
158       // AZ Image.SCALE_SMOOTH
159       final Image image = icon.getImage().getScaledInstance(height, width, Image.SCALE_SMOOTH);
160 
161       return new ImageIcon(image);
162    }
163 
164    /**
165     * Saves an image file to disk in the location specified.
166     * <p>
167     * @param image the image to save
168     * @param filename the file to save it as
169     * @throws IOException if any error occurs writing the file.
170     */
171    public static File saveImage(final Image image, final String filename) throws IOException {
172       final int w = image.getHeight(null);
173       final int h = image.getHeight(null);
174       final BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
175       final Graphics2D g2 = bi.createGraphics();
176       g2.drawImage(image, 0, 0, null);
177       g2.dispose();
178       final File file = new File(filename);
179       ImageIO.write(bi, "jpg", file);
180       return file;
181    }
182 
183    /**
184     * Saves this image file based on a format from prefs. The format is in
185     * aFormat and can have values %y for year, %a for artist, and %d for disc.
186     * Replaces any invalid characters (\\, /, :, , *, ?, ", <, >, or |) with
187     * underscores _ to prevent any errors on file systems. Examples: %a - %d =
188     * Black Crowes - Amorica.jpg
189     * <p>
190     * @param image the image to save
191     * @param aFormat the string format like %a - %d = Black Crowes - Amorica.jpg
192     * @param aDirectory the directory to save the file in.
193     * @param aArtist the name of the artist
194     * @param aDisc the name of the disc
195     * @return true if renamed, false if failure
196     * @throws IOException if any error occurs writing the file out
197     */
198    public static String saveImageWithFileFormat(final Image image, final String aFormat, final String aDirectory,
199             final String aArtist, final String aDisc, final String aYear) throws IOException {
200       String result = null;
201       String newFileName = aFormat;
202       newFileName = StringUtils.replace(newFileName, "%y", aYear);
203       newFileName = StringUtils.replace(newFileName, "%a", aArtist);
204       newFileName = StringUtils.replace(newFileName, "%d", aDisc);
205       newFileName = StringUtils.replace(newFileName, "%A", aArtist.toUpperCase(Locale.US));
206       newFileName = StringUtils.replace(newFileName, "%D", aDisc.toUpperCase(Locale.US));
207       newFileName = FileUtil.correctFileName(newFileName);
208       newFileName = aDirectory + SystemUtils.FILE_SEPARATOR + newFileName + "." + ImageFilter.JPG;
209 
210       result = newFileName;
211 
212       saveImage(image, newFileName);
213 
214       return result;
215    }
216 
217    /** AZ **/
218    public static String saveImageToUserDefinedDirectory(final File imageFile, final String aArtist, final String aDisc,
219             final String aYear) throws IOException {
220       String result = null;
221       String newFileName = settings.getFileFormatImage();
222       int size = settings.getCoverSizeLarge();
223 
224       if (settings.isCopyImagesToDirectory()) {
225          newFileName = standardImageFileName(aArtist, aDisc, aYear);
226          ImageIcon imageIcon = getScaledImage(imageFile.toString(), size, size);
227          Image newImage = imageIcon.getImage();
228          saveImage(newImage, newFileName);
229       }
230       result = imageFile.getAbsolutePath();
231       return result;
232    }
233 
234    /**
235     * Method to create a new ImageIcon and return the reference
236     * <p>
237     * @param aFileName filename of icon to load
238     * @return ImageIcon reference of fileName
239     */
240    private static ImageIcon getIcon(final String aFileName) {
241       return new ImageIcon(ClassLoader.getSystemResource(aFileName));
242    }
243 
244    /** AZ **/
245    public static String standardImageFileName(final String aArtist, final String aDisc, final String aYear) {
246       String newFileName = settings.getFileFormatImage();
247       String fileName = "";
248       String aDirectory = settings.getImagesLocation().toString();
249 
250       newFileName = StringUtils.replace(newFileName, "%y", aYear);
251       newFileName = StringUtils.replace(newFileName, "%a", aArtist);
252       newFileName = StringUtils.replace(newFileName, "%d", aDisc);
253       newFileName = StringUtils.replace(newFileName, "%A", aArtist.toUpperCase(Locale.US));
254       newFileName = StringUtils.replace(newFileName, "%D", aDisc.toUpperCase(Locale.US));
255       newFileName = FileUtil.correctFileName(newFileName);
256       fileName = aDirectory + SystemUtils.FILE_SEPARATOR + newFileName + "." + ImageFilter.JPG;
257       if (fileName.length() > 256) {
258          newFileName = newFileName.substring(0, newFileName.length() - 4 - aDirectory.length());
259          fileName = aDirectory + SystemUtils.FILE_SEPARATOR + newFileName + "." + ImageFilter.JPG;
260          LOG.warn("Image name was too long: " + fileName);
261       }
262       return fileName;
263    }
264 } // end class ImageFactory