Java:快速缩放操作,设置缓冲区的初始大小(图像)

时间:2016-12-07 22:12:00

标签: java swing zooming

我正在考虑在Swing中实现缩放操作(放大/缩小,平移)。主要问题是指需要绘制的1e + 06点/线所代表的数据量。

为了尽可能快地进行变焦操作,采用了以下方法。

1]我使用的是由缓冲图像 img 表示的屏幕外缓冲区。

2]在缩放操作期间,数据仍然是未链接的。不是绘制所有点,而是用屏幕外缓冲区替换当前图像。

g2d.drawImage(img, 0, 0, this);

有一个简单的例子说明了在随机生成的点上放大/缩小的基本操作:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ZoomOperations extends JPanel{
    private boolean repaint;
    private double zoom;
    private List<Point2D.Double> points;
    private AffineTransform at;
    private BufferedImage img;

    public ZoomOperations()   {
            repaint = true;
            zoom = 0.1;
            points = new ArrayList<>();
            at = new AffineTransform();
            img = null;
            Random r = new Random();
            for (int i = 0; i < 100; i++) 
                    points.add(new Point2D.Double(5000 * r.nextDouble(), 5000 * r.nextDouble()));

            addMouseWheelListener(new MouseAdapter() {

                    public void mouseWheelMoved(MouseWheelEvent e) {
                            if (e.getPreciseWheelRotation() < 0) 
                                    zoom = Math.min(zoom+= 0.02,2);
                            else 
                                    zoom = Math.max(zoom-= 0.02,0.01);
                            repaint();
                    }
            });     
    }

     protected void paintComponent(Graphics g) {
            super.paintComponent(g);       
            Graphics2D g2d = (Graphics2D) g;
            if (img == null)
                    img = (BufferedImage)createImage(5000, 5000);
            at = g2d.getTransform();
            at.translate(0, 0);
            at.scale(zoom, zoom);
            g2d.setTransform(at);
            if (repaint){         
                    Graphics2D g2c = img.createGraphics();
                    for (Point2D.Double p:points)
                            g2c.fillOval((int)p.x-50, (int)p.y-50, 50, 50);
                    g2c.dispose(); 
                    repaint = false;  //Only illustrative example
            }

            g2d.drawImage(img, 0, 0, this);
     }      

    public static void main(String[] args) {
            JFrame jf = new JFrame();
            jf.setSize(800, 600);
            jf.add(new ZoomOperations());
            jf.setVisible(true);
    }

}

是否绘制点的决定是使用标志

进行的
private boolean repaint;

缩放操作相对较快,但我不知道如何设置缓冲区的初始大小

img = (BufferedImage) createImage(5000, 5000);  // How to set the size ?

以避免在添加新点时进入缓冲区。关于点坐标X,Y没有先验信息,变焦比为[1 / 100.0,100.0]。请记住,仿射变换会缩小/放大缓冲区的宽度和高度(缩放&lt; 1 / zoom&gt; 1)。

不幸的是,从屏幕外缓冲区中提取的矢量数据不是平滑的,而是光栅化的(像素在放大倍率下可见)......

还有更合适的方法吗?

感谢您的帮助......

0 个答案:

没有答案