-
November 19th, 2011, 09:31 AM
#1
Loading images fast to JLabel icon
Hello,
In my code, im loading a bunch of images to create a sort of gallery,
I want to know if there is a faster way to load images than what i have done here.. it seems really slow and resource intensive
This is my code..
Code:
Thread t = new Thread(){
public void run(){
GlobalVariables.setLoadImageThreads(GlobalVariables.getLoadImageThreads()+1);
if(GlobalVariables.PET_VIEW_IS_ACTIVE){
JLabel imgLabel = new JLabel();
imgLabel.setName(pic.getPreviewName());
imgLabel.setToolTipText("Double click to open");
imgLabel.addMouseListener(new LabelImageMouseListener(tablePictures, pic.getPictureId(), pic.getFilePath()));
//imgLabel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 1, false));
imgLabel.setBorder(BorderFactory.createLineBorder(Color.WHITE, 1));
PictureUtil.setImageToLabelIcon(pic.getFilePath(), pic.getPreviewName(), imgLabel, 100, 100);
panePictures.add(imgLabel);
}
GlobalVariables.setLoadImageThreads(GlobalVariables.getLoadImageThreads()-1);
}
};
loadImageThreads.add(t);
This is the code for PictureUtil.setImageToLabelIcon
Code:
public static void setImageToLabelIcon(String filePath, String previewName, JLabel label, int maxW, int maxH) {
try {
int maxWidth = maxW;
int maxHeight = maxH;
int newWidth = 0;
int newHeight = 0;
if (previewName == null) {
previewName = "000";
}
BufferedImage scaledImage = null;
File previewImg = new File("imgs/" + previewName + ".jpg");
if (previewImg.exists()) {
scaledImage = ImageIO.read(previewImg);
} else {
BufferedImage myPicture = ImageIO.read(new File(filePath));
double percentDrop = 1d;
double percentDrop1 = 1d;
double percentDrop2 = 1d;
double width = myPicture.getWidth();
double height = myPicture.getHeight();
if (width > maxWidth) {
percentDrop1 = maxWidth / width;
}
if (height > maxHeight) {
percentDrop2 = maxHeight / height;
}
if (percentDrop1 > percentDrop2) {
percentDrop = percentDrop2;
} else {
percentDrop = percentDrop1;
}
newWidth = (int) (Math.floor(myPicture.getWidth() * percentDrop));
newHeight = (int) (Math.floor(myPicture.getHeight() * percentDrop));
scaledImage = new BufferedImage(newWidth, newHeight, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = scaledImage.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
graphics2D.drawImage(myPicture, 0, 0, newWidth, newHeight, null);
graphics2D.dispose();
PictureUtil.flushImages(myPicture);
if(!previewName.equals("000"))
PictureUtil.saveImage(scaledImage, previewName, "jpg");
}
label.setIcon((new ImageIcon(scaledImage)));
PictureUtil.flushImages(scaledImage);
} catch (IOException ex) {
Logger.getLogger(PictureUtil.class.getName()).log(Level.SEVERE, null, ex);
}
}
This is the saveImage method im using, note that i only use this when a thumbnail does not exist. If it exists, it just loads the image.
Code:
public static void saveImage(BufferedImage image,String fileName, String ext) {
File dir = new File("imgs/");
if(!dir.exists()){
dir.mkdir();
}
File file = new File("imgs/"+fileName + "." + ext);
try {
if(!file.exists())
ImageIO.write(image, ext, file);
} catch(IOException e) {
System.out.println("Write error for " + file.getPath() +": " + e.getMessage());
}
}
Individually, an image doesnt really take long, but if I want to load 700 images.. this takes minutes...
This is what i did to try to make this faster...
Each thread in this arraylist contains threads from the first piece of code.
Code:
int i = 0;
int limitIncrease = 10;
int nextLimit = limitIncrease;
long timeSpentWaiting = 0;
for(Thread t:loadImageThreads){
if(GlobalVariables.LOAD_IMAGES_FAST && GlobalVariables.PICTURE_TAB_ACTIVE){
limitIncrease = 10;
}else{
limitIncrease = 1;
try {
Thread.sleep(100);
} catch (InterruptedException ex) {
Logger.getLogger(LoadThumbnails.class.getName()).log(Level.SEVERE, null, ex);
}
}
//VALIDATES THAT THE WINDOW IS OPEN, TO AVOID UNNECESSARY LOADING.
if(!GlobalVariables.PET_VIEW_IS_ACTIVE){
break;
}
while(GlobalVariables.getLoadImageThreads() > 0 && i == nextLimit && nextLimit != loadImageThreads.size()){
try {
if(timeSpentWaiting > 10000){
GlobalVariables.setLoadImageThreads(0);
}
timeSpentWaiting += 200;
Thread.sleep(200);
} catch (InterruptedException ex) {
Logger.getLogger(LoadThumbnails.class.getName()).log(Level.SEVERE, null, ex);
}
}
timeSpentWaiting = 0;
if(i==nextLimit){
nextLimit += limitIncrease;
//ONLY UPDATE THE UI IF THE PICTURE TAB IS ACTIVE
if(GlobalVariables.PICTURE_TAB_ACTIVE){
panePictures.updateUI();
}
}
t.start();
i++;
}
i hope someone can help me with this.. thanks in advance
-
November 19th, 2011, 12:01 PM
#2
Re: Loading images fast to JLabel icon
The only reliable way to make anything faster is to run a profiler to find out which bits are taking the time and then run the profiler on your changes to see if they are improving the performance.
This is what i did to try to make this faster...
Each thread in this arraylist contains threads from the first piece of code.
Throwing threads at the problem is not the solution. You may find adding a few threads increases the performance on your machine and decreases it on another machine. Threads will only help if you have idle processors but if the delays are due to I/O bottle necks or 100% CPU usage more threads will just slow things down.
-
November 20th, 2011, 01:22 AM
#3
Re: Loading images fast to JLabel icon
Ok, I ran a profile on my application and discovered that 90% of the loading time comes from
javax.imageio.ImageIO.read
Am i stuck with this, or is there a faster way to read images?
Is this a hard drive problem? or java? or something else?
:S
-
November 20th, 2011, 07:26 AM
#4
Re: Loading images fast to JLabel icon
It could be that loading the size and format of your images just takes time.
You could try changing the image format to see if a different format loads any faster. Reducing the image size (if that is acceptable) will also speed up loading, or use a JPEG format with a high compression value which will reduce the file size without reducing the image size (the image quality will of course be reduced).
-
November 20th, 2011, 09:27 AM
#5
Re: Loading images fast to JLabel icon
Hi,
I already reduce image size, I save a thumbnail in jpeg format that is on average about 3kb.
I tried higher compression but time is not reduced.. so i guess, there really isn't much to be done.
Thanks for you answer
-
November 20th, 2011, 09:39 AM
#6
Re: Loading images fast to JLabel icon
Once a file is down to 3kb compressing it further will make very little difference.
Have you tried a different file format such as png or gif?
Is the speed issue just related to loading the thumbnails or are you loading the full size images as well?
-
November 20th, 2011, 10:15 AM
#7
Re: Loading images fast to JLabel icon
I havent tried other formats..
The first time the user adds images i create the thumbnails, which takes even longer, but once they are created my application only loads the thumbnails, which is what i wanted to fix..
-
November 20th, 2011, 10:32 AM
#8
Re: Loading images fast to JLabel icon
So is your application displaying the GUI immediately with place holders which are replaced as the thumbnails are loaded or is the problem that the GUI takes ages to display.
Do you need to have so many images in one place, can you divide them into sections so you don't have to load so many at a time.
-
November 20th, 2011, 10:37 AM
#9
Re: Loading images fast to JLabel icon
my application adds the images to a JPanel with GridLayout, so, when there are many images, the time it takes for all pictures to be loaded is very long.
I was watching Windows' behaviour when loading images and it's not much faster than my app, but what it does is, it only loads images visible to the user. So I think i will try something like that.
First, add placeholders with a default image, and when the users scrolls to another place, just load whatever pictures are on the screen at the time..
-
November 20th, 2011, 10:06 PM
#10
Re: Loading images fast to JLabel icon
Originally Posted by keang
So is your application displaying the GUI immediately with place holders which are replaced as the thumbnails are loaded or is the problem that the GUI takes ages to display.
Do you need to have so many images in one place, can you divide them into sections so you don't have to load so many at a time.
This proved to be the best solution!
Thanks !
Tags for this Thread
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|