2D-Grafik g2.drawImage() langsam

Planich

Aktives Mitglied
Eigentlich Edit:

[EDIT]@ Marco
Java:
private BufferedImage createImageFromByteArray(int w, int h, byte input[]) 
    {   
        int output[] = new int[input.length];
        for (int i = 0; i < input.length; i++) 
        {
            byte v = input[i];
            int a = 0xFF000000;
            int r = (v & 0xFF) << 16; 
            int g = (v & 0xFF) <<  8; 
            int b = (v & 0xFF) <<  0; 
            output[i] = a | r | g | b;
        }
        BufferedImage result = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
        long t1=System.currentTimeMillis();
        Image im= createImage(new MemoryImageSource(w, h,output , 0, w));//0  
        result.getGraphics().drawImage(im, 0,0,w,h,null);//32-63  
        //result.setRGB(0,0, w, h, output, 0, w);
        System.out.print("create8bitBI   "); System.out.println(System.currentTimeMillis()-t1); 
        return result;
    }
Ich hab mal deine setRGB Methode auskommentiert und das mit dem Image gesetzt wie ich das meinte. An der Stelle sind vorher bei meinem 6MB tiff etwa 130ms vergangen. Jetzt sinds 30ms-60ms und bei jedem vierten Aufruf sinds 140ms (Warum bei jedem vierten Aufruf 140ms?Wenn mir das jemand beantworten kann immer her damit - das ist auch das was ich bei mir meinte, nur da ist es bei jedem zweiten Aufruf der Fall. Hat das was mit dem Garbage Collector zu tun?)
[/EDIT]



[EDIT]Edit die zweite:
Also ihr habt euch ja die ganze Zeit gefragt warum ich da sone komische Berechnung habe. Mir fiel nicht auf, dass ihr einfach Java implizit eure unsigned Werte in signed Werte umrechnen lasst. Das mache ich explizit mit meinen Abfragen. Bei meinen Tests eben fand ich raus, dass meine zusätzlichen Zeilen Code jedoch keinerlei Geschwindigkeitsnachteil bedeuten. Das was Java da implizit macht ist also keinesfalls schneller. Jedoch fange ich das "spratzeln" ab was durch Rundungsfehler an der weiß schwarz Grenze auftritt. Hier zur Demonstration mal ein Bild was ich meine
[/EDIT]
 

Anhänge

  • interpretation des signed bytes beim Zeichnen.PNG
    interpretation des signed bytes beim Zeichnen.PNG
    10,4 KB · Aufrufe: 26
Zuletzt bearbeitet:
S

Spacerat

Gast
Bei mir z.B. ist dieser Bereich dauerhaft von min (Schwarz) bis max (Weiss) in 16 Bit und von 0 bis min wird Weiss und von max bis 65535 Schwarz ausgeblendet. Bei Marco ist's kaum anders aber halt auf Byteebene so wie bei dir.
Und @Marco: Mit kaum meine ich, dass du bei einer deiner Versionen tatsächlich einen gerinfügigen Fehler hast, wodurch mit 0 statt mit 255 ausgeblendet wird. Liegt anscheinend an jenem hier:[JAVA=182]output = (byte)(f * 256);[/code]statt[JAVA=182]output = (byte)(f * 255);[/code]
 

Planich

Aktives Mitglied
So wäre Marcos Code "optimal"

Java:
private static byte[] convertShortToByteArrayClamping(short input[], int min, int max)
    {
        float value = 0;
        byte output[] = new byte[input.length];
        float normalization = 1.0f / (max - min);
        for (int i=0; i<input.length; i++)
        {           
            if (input[i]>min&&input[i]<max)
            {
                value = (input[i]-min)*normalization;
                output[i] = (byte)(value * 256);                
            }
            if (input[i] <= min)
            {
                output[i]=0;
            }
            if (input[i] >= max)
            {
                output[i]=-1;
            }           
        }
        return output;
    }
Das spratzeln ist damit weg


@Spacerat: ok. Kannst du mir die Frage bezüglich des Garbage Collectors beantworten?
 
Zuletzt bearbeitet:
S

Spacerat

Gast
Also ich würde auch auf deb GC tippen, genaueres aber kann auch ich nicht sagen. Im übrigen kann das bei Marco auch passieren. Bei mir allerdings nicht, weil ich "new" nicht so exxessiv verwende. Mal schauen, was passiert, wenn ich meine Version auch auf 8 Bit reduziere.
Was ich aber noch sagen kann... bei Marco wäre das "Spratzeln" auch weg, wenn du mal 255 statt mal 256 nehmen würdest. Die zusätzlichen if's sind überflüssig. 0,9999 * 256 ergeben 255 (Weiss) 1.0 * 256 ergibt 256 bzw. 0 (Schwarz) und da f im bereich von 0 bis 1 liegt...
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Java:
....
        Image im= createImage(new MemoryImageSource(w, h,output , 0, w));//0  
        result.getGraphics().drawImage(im, 0,0,w,h,null);//32-63  
        //result.setRGB(0,0, w, h, output, 0, w);
...
    }
Ich hab mal deine setRGB Methode auskommentiert und das mit dem Image gesetzt wie ich das meinte. An der Stelle sind vorher bei meinem 6MB tiff etwa 130ms vergangen. Jetzt sinds 30ms-60ms....

Aha... das ist interessant. Kann mir kaum vorstellen, was die MemoryImageSource da schneller machen sollte als setRGB... vielleicht spart sie irgendwie geschickt Konvertierungen...?

Auch wenn man bei solchen "einzelnen" Zeitmessunge SEHR vorsichtig sein sollte: Wenn das ein Microbenchmark sein sollte, müßte man das ggf. mehrfach in einer Schleife mit verschiedenen Bildgrößen laufen lassen, und die Gesamtzeit messen.

Dass bestimmte Operationen regelmäßig (also wirklich GENAU(!!!) jedes n-te mal) länger brauchen hatte ich auch bei einem der Tests beobachtet, und konnte es mir spontan auch nicht erklären.... ???:L Am GC kann's kaum liegen, der läuft i.a. nicht so regelmäßig und würde bei größerem Xmx eh erst viel später zuschlagen. Ich würde eher darauf tippen, dass eine bestimmte Anzahl Bilder irgendwo in bestimmten bereichen des VRAM gehalten (also "managed" gehalten) werden können, aber das ist wilde Spekulation....
 

Planich

Aktives Mitglied
Also ich würde auch auf deb GC tippen, genaueres aber kann auch ich nicht sagen. Im übrigen kann das bei Marco auch passieren. Bei mir allerdings nicht, weil ich "new" nicht so exxessiv verwende. Mal schauen, was passiert, wenn ich meine Version auch auf 8 Bit reduziere.
Was ich aber noch sagen kann... bei Marco wäre das "Spratzeln" auch weg, wenn du mal 255 statt mal 256 nehmen würdest. Die zusätzlichen if's sind überflüssig. 0,9999 * 256 ergeben 255 (Weiss) 1.0 * 256 ergibt 256 bzw. 0 (Schwarz) und da f im bereich von 0 bis 1 liegt...

Nein, ich glaub da hast du unrecht
du meinst so?
Java:
private static byte[] convertShortToByteArrayClamping(short input[], int min, int max)
    {   
        float value = 0;
        byte output[] = new byte[input.length];
        float normalization = 1.0f / (max - min);
        for (int i=0; i<input.length; i++)
        {           
            if (input[i]>min&&input[i]<max)
            {
                value = (input[i]-min)*normalization;
                output[i] = (byte)(value * [B]255[/B]);                
            }          
        }
        return output;
    }
das sprazelt
 

Planich

Aktives Mitglied
Dass bestimmte Operationen regelmäßig (also wirklich GENAU(!!!) jedes n-te mal) länger brauchen hatte ich auch bei einem der Tests beobachtet, und konnte es mir spontan auch nicht erklären.... ???:L Am GC kann's kaum liegen, der läuft i.a. nicht so regelmäßig und würde bei größerem Xmx eh erst viel später zuschlagen.

Ich habe aufGrund von nur 2GB Ram und einem nicht gescheit funktionierenden Netbeans keine Möglichkeit per Xmx den Heap zu vergrößern. Mein Heap ist bei 384MB also wollte ich das nicht ausschließen. Wie gesagt mein 28MB Tiff kann ich erst gar nicht reinladen weil der Heap zu klein ist.
 

Marco13

Top Contributor
384MB Klingt nach dem, was für NetBeans selbst allokiert ist, aber nicht für das zu startende Programm. Sicher, dass du an der richtigen Stelle gesucht hast? Auf einer 32bit VM sollten 1.2 GB drin sein, auf einer 64bittigen "beliebig" viel (wie viel RAM die Kiste hat ist prinzipiell egal, notfalls wird auf die Platte ausgelagert, wodurch es ein paar tausend mal langsamer wird...)
 

bERt0r

Top Contributor
@bERt0r: Gut gemacht... Aber hast du dir mal die Anwendungen von Marco und mir angesehen? Da kommt bei dem grossen PNG-Bild im mittleren Abschnitt bei einigen vielen Einstellungen der Regler so ein Gebilde zum Vorschein, dass an "Fischgräten" erinnert (siehe Anhang). Bei deiner Version kann ich einstellen, was ich will, das Gebilde will sich nicht zeigen.

Hmmm weis nicht, Marcos Programm liefert bei mir die gleichen Ergebnisse wie meins und deines zeigt nur Schwarz an bzw. wirft eine NPE. Vielleicht stimmt auch was mit meinem Rechner nicht... Ich bin aber draufgekommen dass ich vielleicht noch einen Fehler in der Berechnung hatte.

Ich poste jetzt nicht nochmal den ganzen Code aber sollte das nicht funktionieren? Mit dem bitweisen & umgehe ich die unsigned Problematik ohne komplizierte Umrechnung und erhalte eine Farbskala wie die von Planich - also 0=Schwarz, 32767=grau, -1=weiß. Als Ergebnis bekomme ich wieder ein shortArray welches ich einfach wieder in den Raster meines Images schreibe.

Java:
private short[] processPixels(short[] imgData, int upper, int lower)
	{
		int ug = Math.min(upper, lower);
		int og = Math.max(upper, lower);
		
		double normalisierung= 0xFFFF/(og - ug);
		short[] pixels = new short[imgData.length];
		int pixel;
		
		for (int i = 0; i < imgData.length; i++)
		{
			pixel = imgData[i] &0xFFFF;
			
			if (pixel >= ug && pixel <= og)
			{
				pixel = (int) (((pixel - ug) * normalisierung));
				
			} else if (pixel < ug)
			{
				pixel = 0;
			} else
			{
				pixel = -1;
			}
			
			pixels[i] = (short) pixel;
		}
		return pixels;
	}

	private synchronized void updateImage()
	{
		long start = System.nanoTime();
		if (image != null)
		{
			int w = image.getWidth();
			int h = image.getHeight();
			
			short[] pixelData = processPixels(shortData, lowerBound, upperBound);
			image.getRaster().setDataElements(0, 0, w, h, pixelData);
			lblImage.repaint();
		}
		long end = System.nanoTime();
		System.out.println("Time to calculate: " + (end - start) / 1e6 + " ms");
	}
[EDIT]Was ich noch vergas, als upper und lower Parameter kommen Werte im Bereich von 0 - 65535[/EDIT]
 

Anhänge

  • GraustufenRegler.java
    8,2 KB · Aufrufe: 5
Zuletzt bearbeitet:
S

Spacerat

Gast
@Planich: Okay, jetzt hab' ich kapiert, was du mit "spratzeln" meinst. Klar, wenn Marco und ich unsere Formeln anwenden, invertieren wir die Werte ausserhalb von ug und og sozusagen nur weil sie noch weiter aufgespreizt werden und es zu Bereichsüberschreitungen kommt. Okay, einverstanden, das Ausblenden macht Sinn. Ich mach's zwar nun etwas anders, kommt aber auf's selbe raus.
@Marco_13: Dein Fehler mit der 255 statt der 256 bleibt aber bestehen. Erst recht dann, wenn du in etwa wie ich ausblendest, weil dann bei der anschliessenden Berechnung als Höchstwert wie gesagt 0 statt 255 herauskommt.
@bERt0r: Bei deiner Version kann ich diese Gräten immer noch nicht sehen, kann mir allerdings nicht erklären warum.

Ich habe meine Version nun noch einmal abgeändert (zip im Anhang), weil mir etwas nicht einleuchten wollte. Warum eigentlich immer die Daten des Rasters (backUp) bei jeder Änderung erneut in das 16Bit-Raster schreiben, wo sich diese Daten doch erst dann ändern, wenn man per Graphics-Object oder per setRGB in dieses Raster zeichnet. Beides tun wir hier ja nicht. Bei einer Änderung sollte also ein "notifyChanged()" auf das SunWritableRaster genügen (ohne dies, schaffe ich den Repaint in 0,nix, leider tut sich dann auch nur genau so viel: null komma nix), damit sich die JVM die neu berechneten Daten beim Repaint über das ColorModel holt. Tatsächlich, es funktioniert. Bei meiner Version werden, wenn überhaupt, nur geringfügig neue Objekte (am allerwenigsten Images, Arrays oder sonstwas) erstellt. Kurzum, ich muss "OwnImage" bei jeder Änderung nur noch neuzeichnen. Das dauert aber immernoch konstant zwischen 130 bis 150ms. Je nachdem wie hoch der Weiss- bzw. Schwarzanteil bei den Einstellungen ist geht es schneller. Das ist aber wie zuvor die Zeit für den gesammten Repaintvorgang. Was mir immer noch nicht einleuchtet, ist, wie Marcos oder bERt0rs Versionen mit all ihren Neuinstanzierungen und ArrayCopys performanter sein können.
 

Anhänge

  • OwnPanel.zip
    2,6 KB · Aufrufe: 5
Zuletzt bearbeitet von einem Moderator:
Ähnliche Java Themen
  Titel Forum Antworten Datum
H Transparent zeichnen mit drawImage in paintComponent Methode AWT, Swing, JavaFX & SWT 3
J drawImage Fehlersuche AWT, Swing, JavaFX & SWT 5
U drawImage mit EPS AWT, Swing, JavaFX & SWT 0
A Problem mit drawImage AWT, Swing, JavaFX & SWT 1
M Graphics.drawImage von unten nach oben abbilden lassen AWT, Swing, JavaFX & SWT 6
L Graphics.drawImage() - Output-Größe entspricht nicht Parametern AWT, Swing, JavaFX & SWT 10
L Border verschwindet durch Graphics.drawImage() AWT, Swing, JavaFX & SWT 4
P Swing Skalieren mit DrawImage macht Linien kaputt AWT, Swing, JavaFX & SWT 6
G .ico drawImage AWT, Swing, JavaFX & SWT 5
B drawImage funktioniert nicht AWT, Swing, JavaFX & SWT 4
B drawImage auf JPanel bleibt ohne Auswirkungen AWT, Swing, JavaFX & SWT 9
K Graphics.drawImage() sehr schnell AWT, Swing, JavaFX & SWT 5
M Graphics.drawImage verlangsamt sich plötzlich AWT, Swing, JavaFX & SWT 15
0 AWT Graphics2D.drawImage() funktioniert nicht mehr korrekt mit Core i7 AWT, Swing, JavaFX & SWT 4
G Graphics.drawImage() AWT, Swing, JavaFX & SWT 6
? Problem mit drawImage: bei Frame ok, bei JPanel nicht AWT, Swing, JavaFX & SWT 4
F Problem mit drawImage() AWT, Swing, JavaFX & SWT 6
M drawImage bremst GUI AWT, Swing, JavaFX & SWT 2
I drawImage AWT, Swing, JavaFX & SWT 4
B drawImage() hängt! AWT, Swing, JavaFX & SWT 18
O performance g2d.drawImage() AWT, Swing, JavaFX & SWT 17
L Bildbewegung mit g.drawImage AWT, Swing, JavaFX & SWT 3
K g.DrawImage unter paintComponent klappt nur beim 1. Aufruf AWT, Swing, JavaFX & SWT 3
S kurze Frage zu drawImage AWT, Swing, JavaFX & SWT 12
F Endlosschleife bei drawImage() AWT, Swing, JavaFX & SWT 4
L Gezeichnetes Image mit DrawImage überzeichnen AWT, Swing, JavaFX & SWT 3
M drawImage mit seltsamen verhalten AWT, Swing, JavaFX & SWT 2
D graphische Ausgabe zu langsam (vsync gzielt abschaltbar?)... AWT, Swing, JavaFX & SWT 13
E Java-TexturePaint sehr langsam AWT, Swing, JavaFX & SWT 9
Tommy135 JFileChooser ist sehr langsam AWT, Swing, JavaFX & SWT 13
M Swing GUI wird nach invokeLater() langsam AWT, Swing, JavaFX & SWT 19
D JavaFX GUI Komponenten werden langsam bei größerer Datenmenge AWT, Swing, JavaFX & SWT 6
J JavaFX Rendering von Canvas sehr langsam AWT, Swing, JavaFX & SWT 2
C Swing GUI extrem langsam - GUI-Code richtig ausführen AWT, Swing, JavaFX & SWT 1
L [Slick2d] Sidescroller/Hintergrundbild sehr langsam AWT, Swing, JavaFX & SWT 3
S Swing JtextPane sau langsam AWT, Swing, JavaFX & SWT 15
P JFrame langsam / seltsames Verhalten AWT, Swing, JavaFX & SWT 6
X JInternalFrame vor Java2D-Zeichnung langsam bzw. Gui friert ein AWT, Swing, JavaFX & SWT 1
H Swing JScrollPane mit "viel Inhalt" scrollt zu langsam (inkl. See-For-Yourself.jar :D) AWT, Swing, JavaFX & SWT 2
D Image soll langsam sichtbar werden AWT, Swing, JavaFX & SWT 4
M JTable mit wechselnden Spalten - sehr Langsam AWT, Swing, JavaFX & SWT 5
A HELP: JFieldText dynamisch setzen -> langsam AWT, Swing, JavaFX & SWT 19
O RandomAccesFile langsam AWT, Swing, JavaFX & SWT 6
lumo AWT Screenshots machen ist langsam? AWT, Swing, JavaFX & SWT 6
J JApplet langsam wegen vielen Tooltips? AWT, Swing, JavaFX & SWT 36
R Image laden sehr langsam AWT, Swing, JavaFX & SWT 7
F Swing JTable langsam AWT, Swing, JavaFX & SWT 13
Kr0e VolatileImage langsam AWT, Swing, JavaFX & SWT 10
A repaint() zu langsam, bitte um alternativen AWT, Swing, JavaFX & SWT 5
A Swing JTextPane sehr langsam AWT, Swing, JavaFX & SWT 6
R TableRowSorter... zu langsam AWT, Swing, JavaFX & SWT 9
Stillmatic JTextPane langsam? AWT, Swing, JavaFX & SWT 5
R JTable für sehr viele Daten sehr langsam AWT, Swing, JavaFX & SWT 20
PAX JList aktualisiert zu langsam beim Hinzufügen von Einträgen AWT, Swing, JavaFX & SWT 6
G JScrollPane scrollt zu langsam AWT, Swing, JavaFX & SWT 6
S Bilder werden sehr langsam geladen AWT, Swing, JavaFX & SWT 4
M jFileChooser extrem langsam AWT, Swing, JavaFX & SWT 15
G Swing Programmstart zu langsam AWT, Swing, JavaFX & SWT 3
J JFileChooser öffnet sich in manchen Fällen extrem langsam! AWT, Swing, JavaFX & SWT 12
D Scrollbalken zu langsam AWT, Swing, JavaFX & SWT 10
S Programm aufgrund von paint() zu langsam AWT, Swing, JavaFX & SWT 18
doctus img.getScaledInstance() sehr rechenintensiv und langsam? AWT, Swing, JavaFX & SWT 3
T Linie langsam zeichnen AWT, Swing, JavaFX & SWT 3
C JButton + JFrame Reaktion SEHR langsam. AWT, Swing, JavaFX & SWT 2
J Double-Buffering zu langsam AWT, Swing, JavaFX & SWT 4
A Warum ist jtable.addRowSelectionIntervall so langsam? AWT, Swing, JavaFX & SWT 10
T Swing bei Realtime-Aktualisierung zu langsam? AWT, Swing, JavaFX & SWT 10
C TreeModel zu langsam für EventDispatchThread AWT, Swing, JavaFX & SWT 5

Ähnliche Java Themen

Neue Themen


Oben