Java: drawing scaled objects (buffered image and vector graphics)

和自甴很熟 提交于 2019-12-23 04:57:23

问题


I would like to draw scaled objects containing raster as well as vector data. Currently, I am drawing into a scaled Graphics2D object

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();
}

Unfortunately, this approach has some disadvantages (affects the Stroke width, worse quality of zoomed images).

Instead of that I would like to draw scaled objects. For the vector data, the approach is simple:

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();
}

However, how to apply the transformation to the buffered image without rescaling the Graphics2D object? This approach does not work

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

because raster image cannot be understood as a vector shape...

Thanks for your help.


回答1:


A possible solution may represent an affine transformation of the raster:

//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);

Unfortunately, this approach is inappropriate for the zoom operations; it is more computationally expensive. For the raster data (JPG, 5000 x 7000 pix) a simple bilinear interpolation

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

takes about 1.5 sec... Conversely, using a scaling Graphics2D object is significantly faster (< 0.1 s), the image can be shifted and zoomed in the real-time.

In my opinion, rescaling objects together with the raster data is slower than rescaling Graphics2D object....



来源:https://stackoverflow.com/questions/40957504/java-drawing-scaled-objects-buffered-image-and-vector-graphics

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!