Screencapture - Image - enormer Speicherverbrauch?

flashray

Erfahrenes Mitglied
Hallo,

habe angefangen einen simplen Colorpicker zu programmieren. Komme allerdings mit dem Speicherverbrauch nicht zurecht. Wie und wo muss ich welche Ressourcen wieder freigeben, damit der Speicherverbrauch nicht ständig steigt?

Das Programm besteht bisher aus zwei Klassen. Die GUI besteht aus einer JFrame welche eine Imagepanel und eine JPanel enthält. In der Imagepanel wird die Umgebung des MouseCursors angezeigt. Der JPanel bekommt die Farbe zugewiesen auf welche der MouseCursor zeigt. Es werden hierzu zwei Threads benutzt.

Was muss ich ergänzen oder verbessern, damit ich den Speicherverbrauch einschränken kann?


Code:
import java.awt.Dimension;
import java.awt.FlowLayout;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Root extends JFrame implements Runnable {

	ImgPanel ip = new ImgPanel();
	Dimension d1 = new Dimension(200,200);
	Dimension d2 = new Dimension(200,100);
	JPanel jp = new JPanel();
	
	public Root(String titel) {
		super(titel);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(200, 300);
		setLocationByPlatform(true);
		setAlwaysOnTop(true);
		setResizable(false);
		
		ip.setPreferredSize(d1);
		ip.setMaximumSize(d1);
		jp.setBorder(BorderFactory.createEtchedBorder());
		
		jp.setPreferredSize(d2);
		jp.setMaximumSize(d2);
		setLayout(new FlowLayout());
		add(ip);
		add(jp);
		
		setVisible(true);
	}

	public static void main(String[] args) {
		Root root = new Root("ColorPix");
		root.startAnimation();
	}
	
	public void startAnimation () {
		Thread th = new Thread(this);
		th.start();
	}

	public void run() {
		while (true) {
			jp.setBackground(ip.c);
			jp.repaint();
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}	
	}
}

Code:
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.PointerInfo;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class ImgPanel extends JPanel implements Runnable{

	int x, y, xx, yy;

	Color c;

	Robot robot;

	PointerInfo info;

	Toolkit tk = Toolkit.getDefaultToolkit();
	
	Rectangle rec;

	BufferedImage image = new BufferedImage(20,20,BufferedImage.TYPE_INT_RGB);

	int mx = 0;

	int my = 0;

	public void paintComponent(final Graphics g) {
		super.paintComponent(g);

		try {
			robot = new Robot();
		} catch (AWTException e) {
			e.printStackTrace();
		}
		
		startAnimation();

		g.drawImage(image, x, y, this.getWidth() - xx - x, this.getHeight()
				- yy - y, this);
		g.drawRect(100,100,10,10);
		g.dispose();
	}

	public void startAnimation () {
		Thread th = new Thread(this);
		th.start();
	}
	
	public void run() {
		while (true) {
			info = MouseInfo.getPointerInfo();
			mx = (int) info.getLocation().getX();
			my = (int) info.getLocation().getY();
			c = robot.getPixelColor(mx, my);
			rec = new Rectangle(mx - 10, my - 10, 20, 20);
			image = robot.createScreenCapture(rec);
			repaint();
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

Vg Erdal
 
Hallo!

Schau mal hier:
Code:
 /**
  * 
  */
 package de.tutorials;
 
 import java.awt.AWTException;
 import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.MouseInfo;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.Robot;
 import java.awt.image.BufferedImage;
 
 import javax.swing.JComponent;
 import javax.swing.JFrame;
 
 /**
  * @author Tom
  * 
  */
 public class SimpleColorPicker extends JFrame {
 	PreviewComponent previewComponent;
 
 	Dimension previewDimension;
 
 	Thread screenGrabber = new Thread() {
 		public void run() {
 			try {
 				Robot robot = new Robot();
 			    while (SimpleColorPicker.this.isDisplayable()) {
 
 				    Point point = MouseInfo.getPointerInfo().getLocation();
 				    point.translate(-previewDimension.width / 2,
 						    -previewDimension.height / 2);
 
 				    BufferedImage screenCapture = robot
 						    .createScreenCapture(new Rectangle(point,
 								    previewDimension));
 				    previewComponent.getGraphics().drawImage(screenCapture, 0,
 						    0, null);
 					try {
 					    sleep(75L);
 				    } catch (InterruptedException e) {
 					    e.printStackTrace();
 					}
 				}
 
 			} catch (AWTException e1) {
 				e1.printStackTrace();
 			}
 		}
 	};
 
 	public SimpleColorPicker() {
 		super("SimpleColorPicker");
 		setDefaultCloseOperation(EXIT_ON_CLOSE);
 		previewComponent = new PreviewComponent();
 		previewDimension = new Dimension(120, 90);
 		previewComponent.setPreferredSize(previewDimension);
 		add(previewComponent);
 		pack();
 		setVisible(true);
 		screenGrabber.start();
 	}
 
 	/**
 	 * @param args
 	 */
 	public static void main(String[] args) {
 		new SimpleColorPicker();
 	}
 
 	class PreviewComponent extends JComponent {
 		protected void paintComponent(Graphics g) {
 			super.paintComponent(g);
 		}
 	}
 }

Gruß Tom
 
Hallo Tom,

dein Code funktioniert problemlos. Schön und gut, aber ich konnte den oder die Fehler im meinem nicht erkennen, da dein Beispiel zu sehr von meinem verschieden ist.

Vg Erdal
 
Hallo!

... kein Wunder schau dir doch mal deine paintComponent(..) Methode an:
Code:
  public void paintComponent(final Graphics g) {
  		super.paintComponent(g);
  
  		try {
  			robot = new Robot();
  		} catch (AWTException e) {
  			e.printStackTrace();
  		}
  		
  		startAnimation();
  
  		g.drawImage(image, x, y, this.getWidth() - xx - x, this.getHeight()
  				- yy - y, this);
  		g.drawRect(100,100,10,10);
  		g.dispose();
  	}

...Du weist schon, dass die bei jedem Zeichnen des Panels aufgerufen wird, oder? ;-)

Ich würde das soch machen:
Code:
  /**
 * 
 */
package de.tutorials;

import java.awt.AWTException;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.MouseInfo;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * @author Tom
 * 
 */
public class SimpleColorPicker extends JFrame {

    JComponent previewComponent;

    Dimension previewDimension;

    Dimension pixelColorDimension = new Dimension(120, 30);

    Dimension drawDimension = new Dimension(120, 90);

    JPanel pixelColorPanel;

    Thread screenGrabber = new Thread() {
        public void run() {
            try {
                Robot robot = new Robot();
                while (SimpleColorPicker.this.isDisplayable()) {

                    Point point = MouseInfo.getPointerInfo().getLocation();
                    Color color = robot.getPixelColor(point.x, point.y);

                    pixelColorPanel.setBackground(color);

                    point.translate(-previewDimension.width / 2,
                            -previewDimension.height / 2);

                    BufferedImage screenCapture = robot
                            .createScreenCapture(new Rectangle(point,
                                    previewDimension));
                    previewComponent.getGraphics().drawImage(screenCapture, 0,
                            0, drawDimension.width, drawDimension.height, null);
                    previewComponent.getGraphics().drawRect(
                            drawDimension.width / 2 - 1,
                            drawDimension.height / 2 - 1, 3, 3);

                    try {
                        sleep(75L);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

            } catch (AWTException e1) {
                e1.printStackTrace();
            }
        }
    };

    public SimpleColorPicker() {
        super("SimpleColorPicker");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        previewComponent = new JPanel();
        previewDimension = new Dimension(36, 27);
        previewComponent.setPreferredSize(drawDimension);
        pixelColorPanel = new JPanel();
        pixelColorPanel.setPreferredSize(pixelColorDimension);
        add(previewComponent, BorderLayout.NORTH);
        add(pixelColorPanel, BorderLayout.SOUTH);
        pack();
        setVisible(true);
        screenGrabber.start();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        new SimpleColorPicker();
    }
}

Gruß Tom
 
Danke Tom.

stimmt die Methode startamination() darf nicht in paintcomponent() sein. Bin mit der GrafikApi nicht so sehr vertraut, hab die Sachen puzzlemäßig zusammengetragen ohne das ich weiß, wie sie intern eigentlich funktioniern. Aber Übung macht den Meister! Falls es doch irgendwo hakt eilen die tutorials.de User und Moderatoren :) .

Vg Erdal
 
Zurück