0

Ich möchte skalierte Objekte zeichnen, die sowohl Raster- als auch Vektordaten enthalten. Derzeit bin ich in einer skalierten Graphics2D Objekt zeichnenJava: Zeichnen skalierter Objekte (gepuffertes Bild und Vektorgrafiken)

protected void paintComponent(Graphics g) { 

    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g.create(); 

    //Get transformation, apply scale and shifts 
    at = g2d.getTransform(); 
    at.translate(x, y); 
    at.scale(zoom, zoom);  

    //Transform Graphics2D object 
    g2d.setTransform(at); 

    //Draw buffered image into the transformed object 
    g2d.drawImage(img, 0, 0, this); 

    //Draw line into transformed Graphics2D object 
    Line2D.Double line = new Line2D.Double(); 
    line.x1 = (int)p1.getX(); 
    line.y1 = (int)p1.getY(); 
    line.x2 = (int)p2.getX(); 
    line.y2 = (int)p2.getY(); 

    g2d.draw(line); 

    g2d.dispose(); 
} 

Leider hat dieser Ansatz einige Nachteile (wirkt sich auf die Strichbreite, schlechter Qualität gezoomten Bilder).

Stattdessen würde ich gerne skalierte Objekte zeichnen. Für die Vektordaten, ist der Ansatz einfach:

protected void paintComponent(Graphics g) { 

    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D) g.create(); 

    //Update affine transformation 
    at = AffineTransform.getTranslateInstance(x, y); 
    at = AffineTransform.getScaleInstance(zoom, zoom); 

    //Transform line and draw 
    Line2D.Double line = new Line2D.Double(); 
    line.x1 = (int)p1.getX(); 
    line.y1 = (int)p1.getY(); 
    line.x2 = (int)p2.getX(); 
    line.y2 = (int)p2.getY(); 

    g2d.draw(at.createTransformedShape((Shape)line)); 

    //Transform buffered image and draw ??? 
    g2d.draw(at.createTransformedShape((Shape)img)); //Error 

    g2d.dispose(); 
} 

jedoch, wie die Transformation auf das gepufferte Bild anzuwenden, ohne das Graphics2D Objekt neu zu skalieren? Dieser Ansatz funktioniert nicht

g2d.draw(at.createTransformedShape((Shape)img)); 

weil Rasterbild nicht als Vektorform verstanden werden kann ...

Vielen Dank für Ihre Hilfe.

+0

Anstelle der Zeile, die mit '// Error' markiert ist, könnten Sie tun' g2d.transform (beim); g2d.drawImage (img, 0, 0, null); '. Wenn Sie Qualitätsprobleme haben, sollten Sie die Rendering-Hinweise von Graphics2D ändern. – Marco13

Antwort

1

kann eine mögliche Lösung, die eine affine Transformation des Rasters darstellen:

//Update affine transformation 
at = AffineTransform.getTranslateInstance(x, y); 
at = AffineTransform.getScaleInstance(zoom, zoom); 

at.translate(x, y); 
at.scale(zoom, zoom);  

//Create affine transformation 
AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_NEAREST_NEIGHBOR); 

//Apply transformation 
BufferedImage img2 = op.filter(img, null); 

//Draw image 
g2d.drawImage(img2, 0, 0, this); 

Leider ist dieser Ansatz für die Zoom-Operationen nicht geeignet ist; es ist rechenintensiver. Für die Rasterdaten (JPG, 5000 x 7000 pix) eine einfache bilineare Interpolation

AffineTransformOp op = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR); 

etwa 1,5 sec dauert ... Im Gegensatz dazu ein Skalierung Graphics2D-Objekt ist deutlich schneller (< 0,1 s), kann das Bild sein verschoben und gezoomt in der Echtzeit.

Meiner Meinung nach, ist Objekte zusammen mit den Rasterdaten rescaling langsamer als Objekt Graphics2D rescaling ....