# Java CoverFlow.



## meckiebro (23. Dezember 2009)

Hallo ich habe eine Frage bezüglich Bilder in Java. Ich habe ein bisschen im Internet gestöbert und bin erstmal über jimi gestoßen. Das war auch garnet so schlecht da war der Speicherverbrauch nicht so hoch und ging soweit. Dann habe ich mit Reflectionen und sowas angefangen und das ging nicht so wie ich wollte. 

So dann habe ich weiter gestöbert und habe mit BufferedImage gearbeitet.
Ich habe erstmal folgendes Problem selbst kleine jpg Dateien fressen massenhaft Speicher. Ich habe darauf hin bei meiner loadMethode folgendes gemacht. Wenn das Bild die 300pixel marke übersteigt wird es geladen und erstmal verkleinert. Dann abgespeichert und dann die verkleinerte Variante geladen. Das Programm erkennt auch ob das Bild bereits verkleinert vorliegt und lädt dann die kleinere Variante im Falle das sie existiert

So wenn ich das ganze jetzt mit 30 und mehr bildern mache ist totale apokalypse. Dann steigt der Speicherverbrauch bis ins unermässliche(bei 350mb habe ich erstmal abgebrochen).
Davon abgesehen das es so seine Zeit braucht die Bilder zu verkleinern. 

Woran liegt der hohe Speicherverbrauch? Gibt es eine Möglichkeit die Bilder nur verkleinert zu laden? Oder etwas woran ich noch garnicht gedacht habe. Ich habe zu laden immer ImageIO.read(...) genutzt.
Ich poste mal die lade Methode.


```
public synchronized void addImage(final String fileString,final int order){
		
		load = new Thread(){
			public void run(){
				try {
					//Reihenfolge beachten
					while(order!=CoverFlow.this.order){
						Thread.sleep(1);
					}
					monitor.enter();
					
					try {
						imageInfo.setInput(new FileInputStream(new File(fileString)));
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					}
					
					if(imageInfo.check()){
						int width=imageInfo.getWidth();
						int height=imageInfo.getHeight();
						if(width>height){
							while(height>300){
								width = (int)(width*(2.0/3.0));
								height = (int)(height*(2.0/3.0));
							}
						}else{
							while(width>300){
								width = (int)(width*(2.0/3.0));
								height = (int)(height*(2.0/3.0));
							}
						}
						File file = new File(fileString);
						File read;
						File exists = new File(file.getName());
						
						if(!exists.exists()){
							BufferedImage bImage=null;
							try {
								bImage = ImageIO.read(file);
							} catch (IOException e) {
								e.printStackTrace();
							}
							bImage = getScaledInstance(bImage,width,height);
							try {
								ImageIO.write(bImage, "jpg", new File(file.getName()));
							} catch (IOException e) {
								e.printStackTrace();
							}
							read = new File(file.getName());
						}else{
							read = new File(file.getName());
						}
						BufferedImage bImg=null;
						try {
							bImg = ImageIO.read(read);
						} catch (IOException e) {
							e.printStackTrace();
						}
						
						for(int i=0;i<images.size();i++){
							CoverFlow.this.images.get(i).setX(CoverFlow.this.images.get(i).getX()+distance);
						}
						
						
						if(CoverFlow.this.images.size()==0){
							CoverFlow.this.currentSelectedImage=0;
						}
						CoverFlow.this.images.add(new ImageObject(bImg,0,0,width,height,0,read));
						
						refresh(currentSelectedImage,false);
					}
					CoverFlow.this.slider.setMaximum(CoverFlow.this.images.size()-1);
					CoverFlow.this.order++;
					monitor.leave();
					CoverFlow.this.repaint();
					
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
			
		};
		
		load.start();
	}
```

Ein bisschen Erklärung zum Code. Also da das Laden etwas brauch habe ich dafür einen Thread bzw mehrere Threads gemacht die von einem Monitor verwaltet werden. Die erste while Schleife sorgt erstmal nur dafür das die Bilder dennoch in der richtigen Reihenfolge geladen werden. ImageInfo dient dazu herrauszufinden wie groß das Bild ist ohne es vorher zu laden. 

Dann wird geprüft ob es verkleinert werden muss. Wenn die Datei bereits existiert wird die verkleinerte Variante geladen....

Hier mal ein kleines Bild was trotz allem schon geht. Bitte jetzt aber nicht von den Covern ablenken lassen^^

http://rapidshare.com/files/325039433/coverflow.jpg


----------



## meckiebro (29. Dezember 2009)

Da bis jetzt mir leider keiner weiter helfen konnte stelle ich mal eine andere Frage.
Ich habe ein bisschen rumgesucht und bin auf WeakReference gestoßen. Wenn ich das richtig verstanden habe kann man darüber fast den GC zwingen ein Object aufzufäumen. 
Hat damit einer schon gearbeitet und könnte mir ein paar Tips geben wie man damit arbeitet?

LG Meckie


----------

