Bildqualität verringern

M

Mr.Bross

Gast
Ich habe den screen jetzt mal als test in 10 Scheiben geteilt. Wenn sich bei einem etwas ändert, wird eine Scheibe verschickt. Das werde ich natürlich noch verbessern, indem ich kleinere Kacheln benutze (vielleicht wirklich 10x10).
Doch mit dieser Geschwindigkeit kann man es vergessen, da es schon alleine zum berechnen etwa 7 Sekunden benötigt. Hier ist mal der Client, bei dem ja alles aufgeteilt wird usw.

Java:
import java.awt.AWTException;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectOutputStream;
import java.net.Socket;

import javax.imageio.ImageIO;

public class Client {

	private BufferedImage imagebefore;
	private boolean who[];

	public static void main(String args[]) throws AWTException, IOException
	{

		new Client().los();

	}

	public void los() throws AWTException, IOException
	{

		Robot robot = new Robot();

		Socket sock;

		sock = new Socket("192.168.0.5", 5005);

		Rectangle rect = new Rectangle();
		rect.x = 0;
		rect.y = 0;
		rect.width = Toolkit.getDefaultToolkit().getScreenSize().width;
		rect.height = Toolkit.getDefaultToolkit().getScreenSize().height;

		ObjectOutputStream ob = new ObjectOutputStream(sock.getOutputStream());

		BufferedReader reader = new BufferedReader(new InputStreamReader(sock
				.getInputStream()));

		int x = 0;

		int y = 0;

		imagebefore = robot.createScreenCapture(new Rectangle(rect));

		int width = Toolkit.getDefaultToolkit().getScreenSize().width;
		int height = Toolkit.getDefaultToolkit().getScreenSize().height;

		who = new boolean[10];

		while (!Thread.interrupted())
		{

			while (!reader.ready())
			{

			}

			if (x == 20)
			{

				x = 0;

				ob.reset();

			}

			String s = reader.readLine();

			if (s.equals("-50"))
			{

				int before = (int) System.currentTimeMillis();

				int pixel2[][] = new int[width][height];

				for (int i = 0; i < 10; i++)
				{

					who[i] = false;

				}

				if (y > 0)
				{

					for (int xx = 0; xx < (width - 1); xx++)
					{
						for (int yy = 0; yy < (height - 1); yy++)
						{
							pixel2[xx][yy] = imagebefore.getRGB(xx, yy);

						}

					}

				}

				BufferedImage bi = robot.createScreenCapture(rect);

				int pixel[][] = new int[width][height];

				for (int xx = 0; xx < (width - 1); xx++)
				{
					for (int yy = 0; yy < (height - 1); yy++)
					{
						pixel[xx][yy] = bi.getRGB(xx, yy);

					}

				}

				for (int xx = 0; xx < (width - 1); xx++)
				{
					for (int yy = 0; yy < (height - 1); yy++)
					{

						pixel[xx][yy] = bi.getRGB(xx, yy);

						if (pixel[xx][yy] != pixel2[xx][yy])
						{

							if (xx < Toolkit.getDefaultToolkit()
									.getScreenSize().height / 10)
							{

								who[0] = true;

							}
							else
								if (xx < Toolkit.getDefaultToolkit()
										.getScreenSize().height / 9)
								{

									who[1] = true;

								}
								else
									if (xx < Toolkit.getDefaultToolkit()
											.getScreenSize().height / 8)
									{

										who[2] = true;

									}
									else
										if (xx < Toolkit.getDefaultToolkit()
												.getScreenSize().height / 7)
										{

											who[3] = true;

										}
										else
											if (xx < Toolkit
													.getDefaultToolkit()
													.getScreenSize().height / 6)
											{

												who[4] = true;

											}
											else
												if (xx < Toolkit
														.getDefaultToolkit()
														.getScreenSize().height / 5)
												{

													who[5] = true;

												}
												else
													if (xx < Toolkit
															.getDefaultToolkit()
															.getScreenSize().height / 4)
													{

														who[6] = true;

													}
													else
														if (xx < Toolkit
																.getDefaultToolkit()
																.getScreenSize().height / 3)
														{

															who[7] = true;

														}
														else
															if (xx < Toolkit
																	.getDefaultToolkit()
																	.getScreenSize().height / 2)
															{

																who[8] = true;

															}
															else
																if (xx < Toolkit
																		.getDefaultToolkit()
																		.getScreenSize().height)
																{

																	who[9] = true;

																}
																else
																{

																}

						}

					}

				}

				System.out.println("after");

				int is = 0;

				for (int i = 0; i < 10; i++)
				{

					if (who[i] == true)
					{

						if (i == 0)
						{
							writer.println("0");
							writer.flush();

							bi = robot.createScreenCapture(new Rectangle(0, 0,
									width / 10, height));

							is = 1;

						}
						else
							if (i == 1)
							{
								writer.println("1");
								writer.flush();

								bi = robot.createScreenCapture(new Rectangle(0,
										0, width / 9, height));

								is = 1;
							}
							else
								if (i == 2)
								{

									writer.println("2");
									writer.flush();

									bi = robot
											.createScreenCapture(new Rectangle(
													0, 0, width / 8, height));

									is = 1;

								}
								else
									if (i == 3)
									{

										writer.println("3");
										writer.flush();

										bi = robot
												.createScreenCapture(new Rectangle(
														0, 0, width / 7, height));

										is = 1;

									}
									else
										if (i == 4)
										{

											writer.println("4");
											writer.flush();

											bi = robot
													.createScreenCapture(new Rectangle(
															0, 0, width / 6,
															height));

											is = 1;

										}
										else
											if (i == 5)
											{
												writer.println("5");
												writer.flush();

												bi = robot
														.createScreenCapture(new Rectangle(
																0, 0,
																width / 5,
																height));

												is = 1;

											}
											else
												if (i == 6)
												{

													writer.println("6");
													writer.flush();

													bi = robot
															.createScreenCapture(new Rectangle(
																	0, 0,
																	width / 4,
																	height));

													is = 1;

												}
												else
													if (i == 7)
													{

														writer.println("7");
														writer.flush();

														bi = robot
																.createScreenCapture(new Rectangle(
																		0,
																		0,
																		width / 3,
																		height));

														is = 1;

													}
													else
														if (i == 8)
														{

															writer.println("8");
															writer.flush();

															bi = robot
																	.createScreenCapture(new Rectangle(
																			0,
																			0,
																			width / 2,
																			height));

															is = 1;

														}
														else
															if (i == 9)
															{

																writer
																		.println("9");
																writer.flush();

																bi = robot
																		.createScreenCapture(new Rectangle(
																				0,
																				0,
																				width,
																				height));

																is = 1;

															}
															else
															{

																System.out
																		.println("nothing (2)");

															}

					}

				}

				if (is == 0)
				{

					writer.println("10");
					writer.flush();

				}

				System.out.println("Time: "
						+ ((int) System.currentTimeMillis() - before));

				ByteArrayOutputStream baos = new ByteArrayOutputStream();

				ImageIO.write(bi, "png", baos);

				byte b[] = baos.toByteArray();

				ob.writeObject(b);
				ob.flush();

				y++;
			}

			x++;

		}

	}
}
 

Marco13

Top Contributor
Hm ... was soll das denn jetzt sein :autsch: ?

Man kann da beliebig viel Zeit reinstecken.

Java:
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.net.ServerSocket;
import java.net.Socket;

import javax.imageio.ImageIO;
import javax.swing.*;
 

public class RobotServer implements Runnable
{
    public static void main(String args[])
    {
        new Thread(new RobotServer()).start();
    }
    
    private static class ImagePanel extends JPanel
    {
        private BufferedImage image;
        
        public ImagePanel(int imageSizeX, int imageSizeY)
        {
            setPreferredSize(new Dimension(imageSizeX, imageSizeY));
            image = new BufferedImage(imageSizeX, imageSizeY, BufferedImage.TYPE_INT_RGB);
        }
        
        public void addTile(Rectangle rectangle, BufferedImage tile)
        {
            Graphics g = image.createGraphics();
            g.drawImage(tile, rectangle.x, rectangle.y, this);
            g.dispose();
            
        }
        
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }
    }
    

    private ImagePanel imagePanel;
    private ServerSocket serverSocket;
    private Socket socket;
    private ObjectInputStream objectInputStream;;
    private PrintWriter writer;
    
    private int width = 300;
    private int height = 300;
    
    public RobotServer()
    {
        try
        {
            SwingUtilities.invokeAndWait(new Runnable()
            {
                public void run()
                {
                    JFrame frame = new JFrame();
                    frame.setVisible(true);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             
                    imagePanel = new ImagePanel(width, height);
                    frame.getContentPane().add(imagePanel);
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        }
        catch (InterruptedException e1)
        {
            e1.printStackTrace();
        }
        catch (InvocationTargetException e1)
        {
            e1.printStackTrace();
        }
        
        
        try
        {
            serverSocket = new ServerSocket(5005);
            socket = serverSocket.accept();
            objectInputStream = new ObjectInputStream(socket.getInputStream());
            writer = new PrintWriter(socket.getOutputStream());
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
    
    public void run()
    {
        try
        {
            while (true)
            {
                writer.println(RobotClient.IMAGE_REQUEST);
                writer.flush();

                while (true)
                {
                    Rectangle region = (Rectangle)objectInputStream.readObject();
                    byte pngData[] = (byte[])objectInputStream.readObject();
                    if (region.width == -1)
                    {
                        break;
                    }
                    BufferedImage image = ImageIO.read(new ByteArrayInputStream(pngData));
                    imagePanel.addTile(region, image);
                }
                imagePanel.repaint();
            }
            
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
 
    }
}


Java:
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import javax.imageio.ImageIO;
 
public class RobotClient implements Runnable
{
    public static final String IMAGE_REQUEST = "-50";
    
    public static void main(String args[]) throws AWTException, IOException
    {
        new Thread(new RobotClient()).start();
    }

    private Robot robot;
    private Rectangle rectangle;
    private ObjectOutputStream objectOutputStream;
    private BufferedReader reader; 
    private BufferedImage previousImage = null;
    private BufferedImage currentImage = null;
    
    public RobotClient()
    {
        try
        {
            robot = new Robot();
            Socket socket = new Socket("127.0.0.1", 5005);
            objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        }
        catch (AWTException e)
        {
            e.printStackTrace();
        }
        catch (UnknownHostException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        
        rectangle = new Rectangle();
        rectangle.x = 0;
        rectangle.y = 0;
        rectangle.width = 300; //Toolkit.getDefaultToolkit().getScreenSize().width;
        rectangle.height = 300; //Toolkit.getDefaultToolkit().getScreenSize().height;
        
        previousImage = new BufferedImage(rectangle.width, rectangle.height, BufferedImage.TYPE_INT_RGB);
    }
 
    
    private List<Rectangle> computeTiles(int numTilesX, int numTilesY) 
    {
        DataBuffer currentDataBuffer = currentImage.getRaster().getDataBuffer();
        DataBufferInt currentDataBufferInt = (DataBufferInt)currentDataBuffer;
        int currentData[] = currentDataBufferInt.getData();

        DataBuffer previousDataBuffer = previousImage.getRaster().getDataBuffer();
        DataBufferInt previousDataBufferInt = (DataBufferInt)previousDataBuffer;
        int previousData[] = previousDataBufferInt.getData();

        int tileSizeX = currentImage.getWidth() / numTilesX;
        int tileSizeY = currentImage.getHeight() / numTilesY;
        
        List<Rectangle> result = new ArrayList<Rectangle>();
        for (int tx=0; tx<numTilesX; tx++)
        {
            for (int ty=0; ty<numTilesY; ty++)
            {
                if (regionsDiffer(previousData, previousImage.getWidth(), 
                    currentData, tx*tileSizeX, ty*tileSizeY, tileSizeX, tileSizeY))
                {
                    Rectangle region = new Rectangle();
                    region.x = tx * tileSizeX;
                    region.y = ty * tileSizeX;
                    region.width = tileSizeX;
                    region.height = tileSizeY;
                    result.add(region);
                }
            }
        }
        return result;
    }
    
    private boolean regionsDiffer(int a[], int stride, int b[], int x0, int y0, int w, int h)
    {
        for (int y=y0; y<y0+h; y++)
        {
            for (int x=x0; x<x0+w; x++)
            {
                int index = y*stride + x;
                if (a[index] != b[index])
                {
                    return true;
                }
            }
        }
        return false;
    }
    
    public void run()
    {
        try
        {
            while (true)
            {
                currentImage = robot.createScreenCapture(rectangle);
                String s = reader.readLine();
                if (s.equals(IMAGE_REQUEST))
                {
                    currentImage = robot.createScreenCapture(rectangle);
                    
                    List<Rectangle> regions = computeTiles(5, 5);
                    System.out.println("Client sending "+regions.size()+" regions");
                    for (int i=0; i<regions.size(); i++)
                    {
                        Rectangle r = regions.get(i);
                        BufferedImage tile = currentImage.getSubimage(r.x, r.y, r.width, r.height);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        ImageIO.write(tile, "png", baos);
                        byte pngData[] = baos.toByteArray();
     
                        objectOutputStream.writeObject(r);
                        objectOutputStream.writeObject(pngData);
                    }
                    objectOutputStream.writeObject(new Rectangle(-1,-1,-1,-1));
                    objectOutputStream.writeObject(new byte[0]);
                    objectOutputStream.flush();
                }
                previousImage = currentImage;
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
 
    }
}
 
Zuletzt bearbeitet:
M

Mr.Bross

Gast
Hi,

dank dir bin ich beim letzten Schritt und es geht auch so weit. Nur leider verstehe ich deinen Quellcode nicht so ganz... Kannst du bitte ein paar Komentare dazugeben?? Wäre echt super!!!

MFG
 

Marco13

Top Contributor
Auch in Kommentare kann man beliebig viel Zeit reinstecken... Ganz kurz, ansonsten präziser fragen:
Java:
    // Der Screenshot wird in numTilesX * numTilesY Tiles zerlegt,
    // diese Methode gibt eine Liste von Rectangles zurück, die
    // die Bereiche beschreiben, die sich seit dem letzten Bild 
    // verändert haben
    private List<Rectangle> computeTiles(int numTilesX, int numTilesY) 
    {
        // Magisch auf die Bilddaten zugreifen: Die Pixel werden damit
        // vom currentImage bzw. previousImage jeweils als int[]-Array abgeholt

        DataBuffer currentDataBuffer = currentImage.getRaster().getDataBuffer();
        DataBufferInt currentDataBufferInt = (DataBufferInt)currentDataBuffer;
        int currentData[] = currentDataBufferInt.getData();
 
        DataBuffer previousDataBuffer = previousImage.getRaster().getDataBuffer();
        DataBufferInt previousDataBufferInt = (DataBufferInt)previousDataBuffer;
        int previousData[] = previousDataBufferInt.getData();
 
        int tileSizeX = currentImage.getWidth() / numTilesX;
        int tileSizeY = currentImage.getHeight() / numTilesY;
        
        List<Rectangle> result = new ArrayList<Rectangle>();

        // Alle Tiles vergleichen
        for (int tx=0; tx<numTilesX; tx++)
        {
            for (int ty=0; ty<numTilesY; ty++)
            {
                // Falls die Tiles sich unterscheiden...
                if (regionsDiffer(previousData, previousImage.getWidth(), 
                    currentData, tx*tileSizeX, ty*tileSizeY, tileSizeX, tileSizeY))
                {
                    // ... ein Rectangle speichern, das den Bereich 
                    // beschreibt in dem sich etwas geändert hat
                    Rectangle region = new Rectangle();
                    region.x = tx * tileSizeX;
                    region.y = ty * tileSizeX;
                    region.width = tileSizeX;
                    region.height = tileSizeY;
                    result.add(region);
                }
            }
        }
        return result;
    }
    
    // Vergleicht zwei rechteckige Bereiche (obere Linke Ecke bei (x0,y0), größe w*h)
    // in Bildern der Breite 'stride', die als int[]-Arrays gegeben sind
    private boolean regionsDiffer(int a[], int stride, int b[], int x0, int y0, int w, int h)
    {
        for (int y=y0; y<y0+h; y++)
        {
            for (int x=x0; x<x0+w; x++)
            {
                int index = y*stride + x;
                if (a[index] != b[index])
                {
                    return true;
                }
            }
        }
        return false;
    }
    
    public void run()
    {
        try
        {
            while (true)
            {
                currentImage = robot.createScreenCapture(rectangle);
                String s = reader.readLine();

                // Warte auf IMAGE_REQUEST
                if (s.equals(IMAGE_REQUEST))
                {
                    currentImage = robot.createScreenCapture(rectangle);
                    
                    // Berechne alle Bereiche, die sich geändert haben
                    List<Rectangle> regions = computeTiles(5, 5);
                    System.out.println("Client sending "+regions.size()+" regions");
                    for (int i=0; i<regions.size(); i++)
                    {
                        Rectangle r = regions.get(i);
                        BufferedImage tile = currentImage.getSubimage(r.x, r.y, r.width, r.height);
                        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                        ImageIO.write(tile, "png", baos);
                        byte pngData[] = baos.toByteArray();
     
                        // Schreibe das Rectangle, das den geänderten Bereich 
                        // beschreibt, und den Inhalt des Bereiches als PNG 
                        objectOutputStream.writeObject(r);
                        objectOutputStream.writeObject(pngData);
                    }

                    // Objekte, die andeuten, dass die Übertragung zuende ist...
                    objectOutputStream.writeObject(new Rectangle(-1,-1,-1,-1));
                    objectOutputStream.writeObject(new byte[0]);
                    objectOutputStream.flush();
                }
                previousImage = currentImage;
            }
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
 
    }
}

 
 
public class RobotServer implements Runnable
{

    // Speichert ein Bild, das gemalt wird
    private static class ImagePanel extends JPanel
    {
        private BufferedImage image;
        
        public ImagePanel(int imageSizeX, int imageSizeY)
        {
            setPreferredSize(new Dimension(imageSizeX, imageSizeY));
            image = new BufferedImage(imageSizeX, imageSizeY, BufferedImage.TYPE_INT_RGB);
        }
        
        // Malt das gegebene Bild an die durch das Rectangle definierte
        // Stelle ins Haupt-Bild
        public void addTile(Rectangle rectangle, BufferedImage tile)
        {
            Graphics g = image.createGraphics();
            g.drawImage(tile, rectangle.x, rectangle.y, this);
            g.dispose();
            
        }
        
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.drawImage(image, 0, 0, this);
        }
    }
    
 


    public void run()
    {
        try
        {
            while (true)
            {
                writer.println(RobotClient.IMAGE_REQUEST);
                writer.flush();
 
                while (true)
                {
                    // Lies das Rechteck und das PNG, das der Client geschickt hat
                    Rectangle region = (Rectangle)objectInputStream.readObject();
                    byte pngData[] = (byte[])objectInputStream.readObject();
                    if (region.width == -1)
                    {
                        break;
                    }
                    BufferedImage image = ImageIO.read(new ByteArrayInputStream(pngData));

                    // Male den Bereich ins Hauptbild
                    imagePanel.addTile(region, image);
                }
                imagePanel.repaint();
            }
 
M

Mr.Bross

Gast
Hi danke. Könntest du bitte DataBuffer genauer erklären?? (+ Methoden) Ich habe mal bei google gesucht und gefunden, dass es irgendwie einzeln die Pixel in ein int-Array speichert (glaube ich zumindest mal =) ). Wenn es so ist, macht es ja eigentlich das gleiche, wie das einzelne Auslesen eines BufferedImages mit getRGB oder??
 

Marco13

Top Contributor
Ja, das ist ein bißchen getrickst. Ein BufferedImage speichert je nach Typ (TYPE_INT_RGB, TYPE_WAS_WEISS_ICH...) die Daten in unterschiedlicher Form. Mal als int[], mal als byte[], mal sonstwie. Das ganze ist ziemlich "wegabstrahiert", d.h. normalerweise sieht man das nicht. Aber wenn man WEISS, dass das ein Bild vom Typ TYPE_INT_... ist, kann man sich den DataBuffer holen, den zu DataBufferInt casten, und sich dann direkt den int[]-Array aus den innersten Innereien des BufferedImages holen.

Das ganze diente nur dem Zweck, das neu-Anlegen und "aufwändige" Füllen des Arrays zu vermeiden. Das Ergebnis ist eigentlich das gleiche wie wenn man einen neuen int[w*h] erstellt, und den mit getRGB(x,y) füllt. Aber nicht ganz: So, wie das da steht, bekommt man DEN Array aus dem BufferedImage (und wenn man da drin Zahlen ändert, ändert sich das Bild! :eek: ). Don't try this at home :D (Man sollte sich schon sicher sein, dass der Typ stimmt, und niemand Mist in den Array reinschreiben kann)
 
M

Mr.Bross

Gast
Eigentlich springt er ja hier:

Java:
 private boolean regionsDiffer(int a[], int stride, int b[], int x0, int y0, int w, int h)
    {
        for (int y=y0; y<y0+h; y++)
        {
            for (int x=x0; x<x0+w; x++)
            {
                int index = y*stride + x;
                if (a[index] != b[index])
                {
                    return true;
                }
            }
        }
        return false;
    }

das erste mal nie rein?? Denn das erste mal beim überprüfen ist y0 immer 0 wie man hier nur unschwer erkennen kann, da ja 0* egal was 0 ergibt...

Java:
 for (int tx=0; tx<numTilesX; tx++)
        {
            for (int ty=0; ty<numTilesY; ty++)
            {
                // Falls die Tiles sich unterscheiden...
                if (regionsDiffer(previousData, previousImage.getWidth(), 
                    currentData, tx*tileSizeX, ty*tileSizeY, tileSizeX, tileSizeY))
                {
                    // ... ein Rectangle speichern, das den Bereich 
                    // beschreibt in dem sich etwas geändert hat
                    Rectangle region = new Rectangle();
                    region.x = tx * tileSizeX;
                    region.y = ty * tileSizeX;
                    region.width = tileSizeX;
                    region.height = tileSizeY;
                    result.add(region);
                }
            }
        }

Das heißt eigentlich ist der erste Durchlauf unnötig... Wieso jedoch fehlt ein großes Stück Fläche, wenn ich mit tx und ty = 1 anfange??
 

Marco13

Top Contributor
Hm... mein Morgenkaffe wirkt wohl noch nicht... ich verstehe nicht ganz, was du meinst... bei
Java:
for (int tx=0; tx<numTilesX; tx++)
        {
            for (int ty=0; ty<numTilesY; ty++)
            {
                // Falls die Tiles sich unterscheiden...
                if (regionsDiffer(previousData, previousImage.getWidth(), 
                    currentData, tx*tileSizeX, ty*tileSizeY, tileSizeX, tileSizeY))
Läuft er für (tx,ty) die Werte durch
(0,0)
(0,1)
(0,2)
...
(1,0)
(1,1)
(1,2)
...

D.h. für eine tileSizeX/Y von 10 ruft er die regionsDiffer-Methode mit diesen Werten für (x0,y0)/(w,h) auf:

(0,0)/(10,10)
(0,10)/(10,10)
(0,20)/(10,10)
...
(10,0)/(10,10)
(10,10)/(10,10)
(10,20)/(10,10)
...

Wenn man sich das mal auf Karopapier aufmalt, sieht man, dass er da Tile-Weise durch das Rechteck läuft.... :bahnhof:
 
M

Mr.Bross

Gast
Erstmal Danke, habe jetzt meinen Denkfehler gefunden =)

Aber wann ist denn region.width -1??

(
Java:
if (region.width == -1)
                    {
                        break;
                    }
)

Ich finde keine Stelle, wo das beim Clienten verschickt wird...
 
M

Mr.Bross

Gast
Und was ist mit diesem hier gemeint:

Java:
SwingUtilities.invokeAndWait(new Runnable() {...}

Was ist SwingUtilities.invokeAndWait?? Ist das etwas anderes wie ein Thread??
 
M

Mr.Bross

Gast
Sry und noch ne letzte Frage =) Wieso kommt diese Exception

Java:
Exception in thread "Thread-2" java.awt.image.RasterFormatException: (y + height) is outside raster
	at sun.awt.image.IntegerInterleavedRaster.createWritableChild(Unknown Source)
	at java.awt.image.BufferedImage.getSubimage(Unknown Source)
	at de.test.byteimage.Client.run(Client.java:151)
	at java.lang.Thread.run(Unknown Source)

wenn ich statt den 300 die komplette Screensize nehme... Ich habe nirgends eine Stelle gefunden wo y + height gerechnet wird und auch so dürfte es überall im Bild bleiben...

PS: Die Exception kommt genau an dieser Stelle:

Java:
BufferedImage tile = currentImage.getSubimage(r.x, r.y,
								r.width, r.height);
 

Marco13

Top Contributor
1. Das rectangle mit Größe -1,-1 wird vom Client in Zeile 133 rausgeschickt:
objectOutputStream.writeObject(new Rectangle(-1,-1,-1,-1));
Das dient dem Zeck, dem Server klarzumachen, dass er jetzt alle Tiles erhalten hat, die sich für EINEN Frame geändert haben, und er jetzt einen neuen IMAGE_REQUEST rausschicken kann.

2. invokeAndWait stellt sicher, dass der enthaltene Codeblock auf dem Event-Dispatch-Thread (EDT) von Swing ausgeführt wird. Das Erstellen und Verändern von JComponents muss auf dem EDT passieren. invokeAndWait wartet dabei (im Gegensatz zu invokeLater) bis das ganze auch fertig ist. Erst danach kann die Übertragung anfangen. Das ganze würde man in einer "richtigen" Anwendung natürlich anders machen (zumindest mit einem Button, der die Übertragung startet) aber .... das sollte ja keine "richtige" Anwendung sein...

3. Das mit der Exception liegt vermutlich(!) daran, dass dort implizit die Annahme drinsteckt, dass die zu übertragende Größe ohne Rest durch die Anzahl der Tiles teilbar ist (d.h. dass alle Tiles gleich groß sind). Mit "computeTiles(5, 5)" und einer Größe von 300x300 haut das hin.

Darüber hinaus solltest du (auch wenn es dir widerstrebt, und dir unnötig anstrengend erscheint) eventuell in Erwägung ziehen, unter Umständen vielleicht ein klizekleines bißchen selbst nachzudenken, WAS dort gemacht werden SOLL und WIE das gemacht werden KANN. Bringt ja nichts wenn du nur durch immer mehr nachfragen Lösungen für Teilprobleme (oder durch meinen Post auch Lösungen für ganze Probleme) zusammenpfriemelst, aber nicht bereit bist, selbst mal einen Blick in die API-Doku zu invokeAndWait zu werfen, mit Strg+F im Programmcode nach dem String "[c]-1[/c]" zu suchen und sofort im Client in Zeile 133 zu landen, oder ein bißchen Zeit zu inverstieren, nachzuvollziehen, was dort mit den Tiles eigentlich passiert...
 

Ähnliche Java Themen

Neue Themen


Oben