# Bilddrehung



## Gast (29. Nov 2007)

Ich hab ein Programm geschrieben, welches ein Bild dreht, da dieses Programm aber sehr sehr sehr langsam ist möchte ich nun wissen, ob es eine möglichkeit gäbe, diese Drehung zu beschleunigen(Java 2D/3D)

Danke


----------



## Marco13 (29. Nov 2007)

Möglicherweise.


----------



## Gast (29. Nov 2007)

und was wäre dass für eine möglichkeit?


----------



## lhein (29. Nov 2007)

Wie soll das jemand beantworten bzw. optimieren, wenn Du nicht mal den Code zeigst?
Wir sind doch keine Heilpraktiker 

lr


----------



## der JoJo (29. Nov 2007)

drehe das bild doch durch manipulation der texture matrix (falls das geht (bei ogl geht das)) das kostet nahezu null performance


----------



## Marco13 (29. Nov 2007)

Da ja nichtmal klar ist, ob es um Java3D oder Java2D geht, (*nochmal nachguck* - zumindest geht es um Java - immerhin DAS steht fest  :wink: ) kann man da kaum was dazu sagen....


----------



## Gast (30. Nov 2007)

//Sommer Erik Maturaprojekt 
//mit Ausgabe

import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage; 
import javax.imageio.ImageIO; 
import java.io.File; 
import java.awt.*;
import java.awt.Color.*;
import java.awt.geom.Ellipse2D; 

public class RGB_rotation { 


    public static void main(String argumente[]) throws java.io.IOException { 

        int hoehe=0, breite=0, x=0, y=0;
        int wert[][];
        BufferedImage bild = ImageIO.read(new File("*.jpeg")); //Bild einlesen

        hoehe=bild.getHeight();    //Einlesen der Höhe des Bildes
        breite=bild.getWidth();    //Einlesen der Breite des Bildes
        System.out.println("Hoehe: "+hoehe);
        System.out.println("Breite: "+breite);



        wert = new int[hoehe][breite]; //Neues Array definieren

        for (x =0; x < breite; x++)    //Schleife die bis zur Breite zählt
        { 
            for (y=0; y < hoehe; y++) {    //Schleife die bis zur Höhe zählt
                Color bild_neu = new Color(bild.getRGB(x,y)); //Farbwerte werden auf Array gelegt
                wert[y][x] = bild_neu.getRGB();     //Farbwerte werden auf array wert[y][x] gelegt
            }
        }

        //    zeichnen

        Frame test = new Frame("Bild");    //Konstruktor erstellt neues Frame
        test.setLocation(400,400); //Position am Bildschirm bestimmen
        test.resize(breite,hoehe);        //Breite und Höhe werden übernommen
        test.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                    System.exit(0);
                }
            });
        test.setVisible(true);

        Graphics g = test.getGraphics(); 


        g.setColor(Color.black); 
        g.fillRect(0,0, breite, hoehe); 
        g.setClip(new Ellipse2D.Double(32,0,285,285));
        // drehen

        for(int a=0; a<360;a++)
        {
            double winkel = Math.toRadians(a); // Java arbeitet mit Radianten

            int gedreht[][] = new int[hoehe][breite];  


            /* für jeden Pixel im neuen Bild wird zurückgerechnet wo er sich
             * im alten Bild befindet, und das danach interpoliert zugewiesen
             */
            for (y=0; y<hoehe; y++) {
                for (x=0; x<breite; x++) {
                    int altX = drehenX(x,y,winkel,breite/2,hoehe/2);
                    int altY = drehenY(x,y,winkel,breite/2,hoehe/2);

                    if (altX >=0 && altX<breite-1 && altY>=0 && altY<hoehe-1) {
                        gedreht[y][x] = linearXYint(altX,altY,wert);
                    } else {
                        gedreht[y][x] = 0; // Schwarzwert wenn nicht mitgedreht
                    }

                }
            }




            for (y=0; y<hoehe; y++) { // Verlust von rund 4-5 fps!!!
                for (x=0; x<breite; x++) {

                    Color c = new Color(gedreht[y][x]);         

                    g.setColor(c);
                    g.drawLine(x, y, x, y);

                }
            }
        }

    }


    //  gibt den Farbwert zurück, wenn der gesuchte Punkt zwischen den ganzzahligen Pixeln liegen würde 
    private static int linearXYint(double x, double y, int[][] bild) { 
        int yu = (int)Math.floor(y);//abrunden
        int yo = (int)Math.ceil(y);//aufrunden

        if (yu==0) {
            linearXint(x, bild[1]);
        } else {
            int wertyu = linearXint(x, bild[yu]);
            int wertyo = linearXint(x, bild[yo]);

            if (yu == yo) {
                return wertyu;
            } else {
                return (int)(wertyo*(y-yu)+wertyu*(yo-y));
            }

        }

        return 0;
    }

    //  gibt den Farbwert zurück, wenn der gesuchte Punkt X horizontal zwischen den 2 Pixeln liegen würde
    private static int linearXint (double x, int[] bild) {
        int xu = (int)Math.floor(x); //abrunden
        int xo = (int)Math.ceil(x);  //aufrunden

        if (xu == 0) {
            return bild[0];
        } else {
            if (xu == xo) {
                return bild[xu];
            } else {
                return (int)(bild[xu]*(xo-x)+bild[xo]*(x-xu));
            }
        }

    }

    private static int drehenX(int pX, int pY, double winkel, int mitteX, int mitteY) {
        return (int)(Math.cos(winkel)*(pX-mitteX)+Math.sin(winkel)*(pY-mitteY)+mitteX);
    }
    private static int drehenY(int pX, int pY, double winkel, int mitteX, int mitteY) {
        return (int)(-Math.sin(winkel)*(pX-mitteX)+Math.cos(winkel)*(pY-mitteY)+mitteY);
    }
}



```

```


----------



## EgonOlsen (30. Nov 2007)

Das sieht extrem unoptimal aus und geht mit Sicherheit schneller. Ein Beispiel: www.jpct.net/download/misc/rotty.zip (CRSR-> scrollen, SHIFT+CRSR->Drehen, PageUP/Down->Zoomen).


----------



## Marco13 (30. Nov 2007)

Das IST *extrem* unoptimal  :autsch: 

Wenn es nur darum geht, ein gedrehtes Bild in Java2D zu zeichnen:


```
public void paintComponent(Graphics gr)
{
    Graphics2D g = (Graphics2D)gr;
    g.rotate(winkel);
    g.drawImage(image,0,0,this);
}
```
und gut is' 

P.S: NIE 'getGraphics' auf einer Component aufrufen!!!


----------



## EgonOlsen (30. Nov 2007)

Marco13 hat gesagt.:
			
		

> P.S: NIE 'getGraphics' auf einer Component aufrufen!!!


P.P.S.: Nie nie sagen. "NIE" ist zu pauschal. Das kann sinnvoll sein.


----------



## Marco13 (30. Nov 2007)

Psssst :wink: (Wer weiß, WIE und WANN man es aufrufen darf, weiß schon, dass diese Einschränkung sich an die Einsteiger richtet, die dazu neigen, sich einmal das Graphics von einem Frame zu holen und dann ein Applikationsleben lang darin rumzeichnen wollen....)


----------

