Hallo,
ich verwende einen FileChooser, und in diesem eine Thumbnaildarstellung für jpeg, png usw.
Hierzu verwende ich bislang folgende Implementierung:
Spezialisierter FileChooser
Image-Berechnung
Ich habe nun das Problem, dass das ganze furchtbar inperformant ist unter Java 1.4.2. Um ein Verzeichnis mit etwa 100 jpegs mit einer Größe zwischen 2kb und 1000kb zu öffnen benötigt das ganze auf einem potenten Rechner etwa 30 Sekunden.
Was kann ich ändern, um die Geschwindigkeit zu erhöhen? Seht ihr große Optimierungsmöglichkeiten?
Ich habe hier
http://java.sun.com/developer/technicalArticles/javase/6_desktop_features_2/
(etwa in der Mitte) etwas über enorm gestiegene Bildverarbeitungsperformance unter Java 6 gelesen.
Kann ich davon provitieren? Gibt es einen anderen Weg?
Gruß, Taste
ich verwende einen FileChooser, und in diesem eine Thumbnaildarstellung für jpeg, png usw.
Hierzu verwende ich bislang folgende Implementierung:
Spezialisierter FileChooser
Code:
public class ImageFileChooser extends JFileChooser
{
private static final Dimension MAX_IMAGE_SIZE_DEFAULT = new Dimension(40, 40);
private static final long serialVersionUID = 1L;
private final Dimension maxImageSize;
public ImageFileChooser(File startDirectory, Dimension maxImageSize)
{
super(startDirectory);
this.maxImageSize = maxImageSize;
}
public Icon getIcon(File f)
{
if (f.isFile())
{
GUITools.showAutoWaitCursor(this);
try
{
Icon aux = new ImageIcon(f.getAbsolutePath());
int w = aux.getIconWidth();
int h = aux.getIconHeight();
if (w > 0 && h > 0)
{
if (w <= maxImageSize.width && h <= maxImageSize.width)
return aux;
ImageTool tool = new ImageTool(f);
double heightToWidth = ((double) h) / ((double) w);
while (w > maxImageSize.width || h > maxImageSize.height)
{
// ...Bildgrößen werden angepasst... }
}
tool.scale(w, h);
return new ImageIcon(tool.getImage());
}
}
catch (Exception e)
{
// return super...
}
}
return super.getIcon(f);
}
}
Image-Berechnung
Code:
public class ImageTool
{
private final Image sourceImage;
private Image transformedImage = null;
private static JComponent mediaTrackerComponent = new JComponent();
private static MediaTracker mediaTracker = new MediaTracker(
mediaTrackerComponent);
private static int nextMediaTrackerId = 0;
public ImageTool(File file) throws IOException
{
//this(Toolkit.getDefaultToolkit().createImage(file.getAbsolutePath()));
String mimeType = getMIMEType(file);
if (mimeType != null && mimeType.toUpperCase().startsWith("IMAGE"))
{
sourceImage = Toolkit.getDefaultToolkit().createImage(
file.getAbsolutePath());
}
else
{
throw new RuntimeException("File is not an image");
}
}
public void scale(Integer width, Integer height)
{
Validate.isTrue(
width != null || height != null,
"either width, height or both must be specified");
Validate.isTrue(
width == null ? true : width.intValue() > 0,
"width must be positive");
Validate.isTrue(
height == null ? true : height.intValue() > 0,
"height must be positive");
// we have to wait for the source image to be loaeded completely
// before the transformation can be done
this.waitForImageLoaded();
if ((width != null) && (this.getSourceWidth() <= width.intValue()))
{
width = new Integer(this.getSourceWidth());
}
if (height == null)
{
double scaleFactor = (double) width.intValue()
/ (double) this.getSourceWidth();
height = new Integer((int) (this.getSourceHeight() * scaleFactor));
}
else if (width == null)
{
double scaleFactor = (double) height.intValue()
/ (double) this.getSourceHeight();
width = new Integer((int) (this.getSourceWidth() * scaleFactor));
}
ImageFilter scaleFilter = new ReplicateScaleFilter(width.intValue(),
height.intValue());
ImageProducer imageProducer = new FilteredImageSource(
this.sourceImage.getSource(), scaleFilter);
this.transformedImage = Toolkit.getDefaultToolkit().createImage(
imageProducer);
}
public void waitForImageLoaded()
{
waitForImage(this.sourceImage);
}
/**
* Wait until the specified image is loaded.
*/
private synchronized static void waitForImage(Image image)
{
Validate.notNull(image);
int id = getNextMediaTrackerId();
mediaTracker.addImage(image, id);
try
{
try
{
mediaTracker.waitForID(id);
}
catch (InterruptedException exc)
{
throw new RuntimeException("interrupted while waiting for image",
exc);
}
if (mediaTracker.isErrorID(id))
{
throw new RuntimeException("error while loading image");
}
}
finally
{
mediaTracker.removeImage(image);
}
}
private synchronized static int getNextMediaTrackerId()
{
return nextMediaTrackerId++;
}
public static String getMIMEType(File file)
{
if (!file.exists())
throw new IllegalArgumentException("File does not exit!");
if (file.isDirectory())
return "directory";
try
{
return file.toURI().toURL().openConnection().getContentType();
}
catch (IOException e)
{
throw new IllegalArgumentException(e.getMessage());
}
}
// ...einige Getter und Setter...
}
Ich habe nun das Problem, dass das ganze furchtbar inperformant ist unter Java 1.4.2. Um ein Verzeichnis mit etwa 100 jpegs mit einer Größe zwischen 2kb und 1000kb zu öffnen benötigt das ganze auf einem potenten Rechner etwa 30 Sekunden.
Was kann ich ändern, um die Geschwindigkeit zu erhöhen? Seht ihr große Optimierungsmöglichkeiten?
Ich habe hier
http://java.sun.com/developer/technicalArticles/javase/6_desktop_features_2/
(etwa in der Mitte) etwas über enorm gestiegene Bildverarbeitungsperformance unter Java 6 gelesen.
Kann ich davon provitieren? Gibt es einen anderen Weg?
Gruß, Taste