2017-02-01 5 views
0

Ich mache ein Programm, das ein bisschen wie Paint Licht ist, und ich bin zu dem Punkt, wo ich möchte, dass der Benutzer in der Lage, elliptische Regionen auswählen können. Mein erster Gedanke ist, dass es eine Art von Gleichung geben muss, die es mir ermöglicht, eine Ellipse basierend auf der Breite und Höhe eines Rechtecks ​​zu konstruieren. Allerdings habe ich bisher nichts ganz so geradliniges gefunden.Konstruieren Ellipse von Rechteck

Hier ist mein Code für einen rechteckigen Bereich auswählt, wenn der Benutzer die Maus zieht (das innerhalb eines Mouseadapters befindet):

 @Override 
     public void mouseDragged(MouseEvent e) { 
       dragPoint = e.getPoint(); 
       if (selectionType.equalsIgnoreCase("Rectangle")) { 
       int width = dragPoint.x - mouseAnchor.x; 
       int height = dragPoint.y - mouseAnchor.y; 
       subHeight = height; 
       subWidth = width; 
       int x = mouseAnchor.x; 
       int y = mouseAnchor.y; 

       if (width < 0) { 
        x = dragPoint.x; 
        width *= -1; 
       } 
       if (height < 0) { 
        y = dragPoint.y; 
        height *= -1; 
       } 
       selectionPane.setBounds(x, y, width, height); 
       selectionPane.revalidate(); 
       repaint(); 
      } 
    } 

SelectionPane ist eine Instanz einer Klasse, die benutzerdefinierten JPanel erstreckt. Die Idee ist, dass ich eine gefüllte Ellipse aus der ausgewählten Region zeichnen möchte, damit der Benutzer sehen kann, was er ausgewählt hat.

Der zweite Teil dieses Programms ist, wo ich auch etwas Verwirrung stifte. Nachdem der Benutzer seine Auswahl getroffen hat, möchte ich eine Maske auf die Bildbits anwenden, indem ich den ausgewählten Bereich als Richtlinie benutze. Also arbeite ich auch mit Byte-Arrays. Wie finde ich heraus, welche Bytes in einem berechneten Oval basierend auf der Breite, Höhe und dem Ursprung des Unterbildes enthalten sind? Unten ist der Code, wo ich das Teilbild basierend auf einer rechteckigen Auswahl (als Referenz) erhalten:

 @Override 
     public void mouseReleased(MouseEvent e) { 
      if (subWidth != 0 && subHeight != 0) { 
       try { 
        //numCols * (numRows - 1) + xPos 
        int startPos = img.getWidth() * (img.getHeight() - 1) + mouseAnchor.x;//the starting position for the total byte array of the original image. The mask will start here. 
        Main.setStartingPos(startPos); 
        Main.setSubImage(img.getSubimage(mouseAnchor.x, mouseAnchor.y, Math.abs(subWidth), Math.abs(subHeight))); 
        ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
        ImageIO.write(Main.getSubImage(), "bmp", baos); 
        Main.setImageRegion(baos.toByteArray()); //sets the region bytes in the Main class 

        Main.generateImageMask();//generates the mask after everything's been calculated. 
       } catch (IOException ex) { 
        Logger.getLogger(SelectionRectangle.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 

Vielen Dank im Voraus. Lassen Sie mich wissen, ob ich meine Frage besser klären kann.

Antwort

1

Sie können die Ellipse aus dem Rechteck erhalten wie folgt:

Ellispe2D.Double el=new Ellispe2D.Double(x, y, width, height); 

Dann können Sie die Positionen unter der Ellipse bedeckt Maske wie folgt:

Rectangle r=el.getBounds(); 
for(i=0; i<r.width; i++) 
    for(j=0; j<r.height; j++) 
    if(el.contains(r.x+i, r.y+j)) ... do whatever with this pixel add it to a list etc 

-

Für Pixel r.x + i, r.y + j können Sie die RGB erhalten und daraus die einzelnen Bytes:

int pixel=image.getRGB(r.x+i, r.y+j); 
int red=(pixel&0x00ff0000)>>16, green=(pixel&0x0000ff00)>>8, blue=pixel&0x000000ff; 
+0

Es ist wie dieser Lösung sieht vielleicht die einfachste, aber da ich mit einer Reihe von Bytes für das Bild arbeiten, gibt es eine So kann ich die Bytes von jedem Pixel im Rechteck extrahieren? Ich sehe keine integrierte Funktionalität dafür. – Sarah

+0

Ich habe gerade an etwas gedacht. Es könnte ein bisschen seltsam sein, aber was ist, wenn ich diese Pixelposition (r.x + i, r.y + j) nehme und daraus eine kleine Sub BufferedImage mache, dann entpacke ich die Bildbytes von dieser kleinen BufferedImage? Könnte das funktionieren? – Sarah

+0

das würde als ein extremes Maß 1x1 Bild funktionieren - Ich weiß nicht, wie Sie es tun werden - aber es könnte unnötig sein - Ich werde versuchen, eine Lösung oben zu setzen – gpasch

1

für Achse alligned Ellipse verwenden Parametergleichung (centric)

x = x0 + rx*cos(a) 
y = y0 + ry*sin(a) 


x0,y0 ist Ellipse Zentrum
rx,ry Halb sind axises Größen (halbe Größe des Rechtecks ​​Seiten)
a ist Winkel Punkt, den Sie wollen zu erhalten

die Region wird normalerweise nach Winkelintervall ausgewählt. Die Winkel werden in der Regel durch eine Linie vom Zentrum (x0,y0) zur tatsächlichen Position des Mauszeigers (mx,my) oder einen Kontrollpunkt als

a = < a0,a1 > so bestimmt, wo ai = { a0,a1 } Ihr Intervall Winkel sind. für die vollständige Ellipse a =< 0,2*M_PI> [rad]

, die gerade umkreisen Angleichung der Winkel so, wenn Sie genauere Winkel sucht

Oder gelten Kreis/Ellipse Korrektur Skalierung erhalten möchten. ..