Redimensionar imagem mantendo a posição do zoom

5 respostas
Borto

Boa noite a todos,
Encontrei vários tópicos aqui no fórum falando sobre afins, mas nenhum que especifique a minha duvida.
Estou desenvolvendo uma aplicação que possui um campo de imagem; este campo deve possuir opção de zoom e surgiu a idéia de fazer no scrool do mouse, porém não consegui redimensionar a imagem e manter a posição onde o mouse se encontra, como no visualizador de imagens do windows ou adobePDF, deve dar zoom baseado no ponto onde o mouse se encontra

Se alguém puder ajudar com a posição da imagem na tela…

5 Respostas

ViniGodoy

Se seu mouse se encontrada em (10,20) e você deu um zoom de 2x, você deve reposicionar a imagem de modo que mouse aponte agora para o pixel (20,40).

Borto
Olá,

Obrigado pela resposta;

Mas é exatamente o calculo para reposicionar a imagem que eu não estou conseguindo fazer, por exemplo, a imagem é de 100X100 e o ponto inicial da imagem está em 0,0, tendo o mouse em 10,20, dou zoom de 2x o início da imagem deve estar em algo em torno de -10,-20 e -5,-10;

e ao voltar o zoom sem mover o mouse o mouse deve estar em 10,20 e o início da imagem em 0,0.

porém ainda não consegui fazer o cálculo para que desse zoomIn e zoomOut corretamente.

ViniGodoy

É isso mesmo. O pixel (20,40) terá que se manter na posição (10,20). Portanto, o início da imagem estará em (-10, -20).

Agora, existem problemas de arredondamento. Então se você quiser que o zoom out e in sempre voltem no mesmo pixel, guarde a posição do pixel inicial em variáveis. Caso contrário, será impossível restaura-la em pixels ímpares.

Borto
Cara encontrei a sua classe JImagePanel e fiz algo mais ou menos como eu queria. Só não sei se esta é a melhor forma de fazer isto, mas funciona, só falta implementar limite para o zoom e posicionamento no centro da tela quando o zoom for menor do que a janela.
public class JImagePanel extends JPanel {

    private BufferedImage background = null;
    private int larg;
    private int alt;
    private int posX;
    private int posY;
    private final double ESCALA = 1.2;

    public JImagePanel(BufferedImage img) {
        if (img == null) {
            throw new NullPointerException("Buffered image cannot be null!");
        }
        this.background = img;
        this.larg = background.getWidth();
        this.alt = background.getHeight();
        this.posX = 0;
        this.posY = 0;

    }

    public JImagePanel(File imgSrc) throws IOException {
        this(ImageIO.read(imgSrc));
    }

    public JImagePanel(String fileName) throws IOException {
        this(new File(fileName));

    }

    public void zoomIn(int x, int y) {
        int vX = x - posX;
        int vL = larg;
        int vY = y - posY;
        int vA = alt;
        larg = (int) (larg * ESCALA);
        alt = (int) (alt * ESCALA);
        posX = (int) (x - (vX * larg / vL));
        posY = (int) (y - (vY * alt / vA));
        repaint();
    }

    public void zoomOut(int x, int y) {
        int vX = x - posX;
        int vL = larg;
        int vY = y - posY;
        int vA = alt;
        larg = (int) (larg / ESCALA);
        alt = (int) (alt / ESCALA);
        posX = (int) (x - (vX * larg / vL));
        posY = (int) (y - (vY * alt / vA));
        repaint();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();
        g2d.drawImage(background, posX, posY, larg, alt, this);
    }
}

No zoom eu passo a posição do mouse;

Borto

Lógico que a melhor forma de fazer o zoom out é armazenando os valores a posição de inicio da imagem;
Dessa forma a imagem não retorna na mesma proporção em função do arredondamento, mas achei interessante fazer assim.

Criado 10 de dezembro de 2012
Ultima resposta 13 de dez. de 2012
Respostas 5
Participantes 2