CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10
  1. #1
    Join Date
    Oct 2011
    Posts
    9

    Unhappy 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

  2. #2
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    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.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  3. #3
    Join Date
    Oct 2011
    Posts
    9

    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

  4. #4
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    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).
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  5. #5
    Join Date
    Oct 2011
    Posts
    9

    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

  6. #6
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    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?
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  7. #7
    Join Date
    Oct 2011
    Posts
    9

    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..

  8. #8
    Join Date
    May 2006
    Location
    UK
    Posts
    4,473

    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.
    Posting code? Use code tags like this: [code]...Your code here...[/code]
    Click here for examples of Java Code

  9. #9
    Join Date
    Oct 2011
    Posts
    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..

  10. #10
    Join Date
    Oct 2011
    Posts
    9

    Re: Loading images fast to JLabel icon

    Quote Originally Posted by keang View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured