简体   繁体   中英

Good practice for drawing and zooming image?

I have a JScrollPane with a JPanel where I can draw by mouse and code. I need the possibility to zoom on details in my drawing. But soon I get a outOfMemoryError. I think because I make my drawing to big while zooming. This is my code:

    private BufferedImage _bufferedImage;
private int _panelWidth = 2000, _panelHeight = 1500;

@Override
public void paintComponent(Graphics g){
    super.paintComponent(g);
    if(_bufferedImage != null){
        g.drawImage(_bufferedImage, 0, 0, this);
    }
}

public void draw(float zoomFactor){
    try {
        int width = (int)(_panelWidth * zoomFactor);
        int height = (int)(_panelHeight * zoomFactor);
        _bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = _bufferedImage.createGraphics();
        g2.setBackground(Color.WHITE);
        g2.setPaint(Color.BLACK);
        g2.scale(zoomFactor, zoomFactor);
        drawHouse(g2); ...
        g2.dispose();
    } 
    catch (Exception e) {
        e.printStackTrace();
    }
    repaint();
}

There must be better practice then what I did.

I can just draw the area of the scrollpane, but then I can't use the scrollbars, then I have to use buttons with arrow up, right, left, down to scroll in my drawing. Anyone who can me give a hint?

but then I can't use the scrollbars

Scrollbars work when the preferred size of the component is greater than the size of the scrollpane. If you are zooming the image in the paintComponent() method then you would also need to override the getPreferredSize() method to return the appropriate size of the image that takes into account the zooming factor.

So in your case the preferred size would be the size of your image.

If you want to zoom in, I am assuming you are no trying to make "bigger pixels", but to draw the same figures at a higher scale. In that case, you should not be using a BufferedImage at all -- instead, you should draw to a suitably scaled JPanel or similar. You can always take a snapshot of whatever you are rendering whenever you need it; but rendering to a BufferedImage without need is wasteful (of time and memory).

See this answer for details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM