Avatar billede myplacedk Nybegynder
22. december 2003 - 12:40 Der er 4 kommentarer og
1 løsning

Skaleret visning af billede

Målet er, at der i en JPane el. lign. vises et billede, som er skaleret så det fylder så meget som muligt, uden at blive større end der er plads til.

Jeg har to problemer nu:

1) Billedet bliver slet ikke vist, skaleret eller ej. (Jeg får bare et vindue med grå baggrund.)
2) Jeg vil gerne skalere ved at angive størrelsen, i stedet for at bruge faktorer.

(Jeg har tjekket at det ikke er filnavnet der er forkert, hvis jeg ændrer det til noget forkert får jeg en fejl.)

Min test ser sådan ud lige nu:

import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;

public class Test extends JFrame {

    public static void main(String[] args) {
        JFrame test = new Test();
    }

    public Test() {
        Component component;
        Image image;
        MediaTracker mediaTracker;
        BufferedImage bufferedImage;
        Graphics2D graphics2D;

        setSize(640, 480);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        component = this.getContentPane();
        image =
            component.getToolkit().getImage(
                "test.jpg");

        mediaTracker = new MediaTracker(component);
        mediaTracker.addImage(image, 0);
        try {
            mediaTracker.waitForAll();
        } catch (InterruptedException ie) {
        }

        bufferedImage =
            new BufferedImage(
                image.getWidth(component),
                image.getHeight(component),
                BufferedImage.TYPE_INT_RGB);

        graphics2D = bufferedImage.createGraphics();
        graphics2D.scale(.5, .5);
        graphics2D.drawImage(image, 0, 0, component);

        setVisible(true);
    }
}
Avatar billede _carsten Nybegynder
22. december 2003 - 13:30 #1
I klassen Test, skal du override paint(), smid nedenstående ind i Test

    public void paint(java.awt.Graphics g){
        graphics2D = (Graphics2D)g;
        graphics2D.drawImage(image, 0, 0, this);
    }


        image =
            component.getToolkit().getImage(
                "test.jpg").getScaledInstance(getWidth(), getHeight(),Image.SCALE_SMOOTH);


Husk iøvrigt:  import java.awt.*;
Avatar billede _carsten Nybegynder
22. december 2003 - 13:42 #2
De lokale variable skal selvfølgelig ændres til instans variable
Avatar billede myplacedk Nybegynder
22. december 2003 - 14:58 #3
Tak for hjælpen.

Jeg har lavet en lille klasse, der wrapper alt det besværlige. :)
Jeg mangler blot at få den til ikke at ændre proportioner, og at finde ud af hvorfor den er så langsom. ;-)


import java.awt.*;
import javax.swing.*;

/**
* @author Niels Andersen <niels@myplace.dk>
*
*/
public class MyImage extends JPanel {

    private Image image;

    public MyImage(String path, Dimension size, Component component) {
        MediaTracker mediaTracker = new MediaTracker(component);

        image =
            component.getToolkit().getImage(path).getScaledInstance(
                size.width,
                size.height,
                Image.SCALE_SMOOTH);

        mediaTracker.addImage(image, 0);
        try {
            mediaTracker.waitForAll();
        } catch (InterruptedException ie) {
        }

        add(new JLabel(path));
        System.out.println(path);
        setVisible(true);
    }

    public void paint(java.awt.Graphics g) {
        Graphics2D graphics2D = (Graphics2D) g;
        graphics2D.drawImage(image, 0, 0, this);
    }
}
Avatar billede _carsten Nybegynder
22. december 2003 - 15:07 #4
Jeg ved ikke om det er MediaTracker som gør det langsomt, men i realiteten kan du godt fjerne det.

Nedenstående burde fungere.

public class MyImage extends JPanel {

    private Image image;

    public MyImage(String path, Dimension size, Component component) {

        image =
            component.getToolkit().getImage(path).getScaledInstance(
                size.width,
                size.height,
                Image.SCALE_SMOOTH);

        add(new JLabel(path));
        System.out.println(path);
    }

    public void paint(java.awt.Graphics g) {
        Graphics2D graphics2D = (Graphics2D) g;
        graphics2D.drawImage(image, 0, 0, this);
    }
}
Avatar billede myplacedk Nybegynder
22. december 2003 - 15:43 #5
Jeg har leget lidt med det. Hvis jeg fjerner MediaTracker bliver metoden færdig langt hurtigere. Men til tager det mange gange længere tid før billedet kommer frem.

Jeg har modificeret i min klasse, så den også tager hensyn til proportioner. Nu er der to MediaTrackers, men umiddelbart ser det ikke ud til at køre langsommere:


import java.awt.*;
import javax.swing.*;

/**
* @author Niels Andersen <niels@myplace.dk>
*
*/
public class MyImage extends JPanel {

    private Image image;

    public MyImage(String path, Dimension size, Component component) {
        MediaTracker mediaTracker = new MediaTracker(component);

        image = component.getToolkit().getImage(path);

        mediaTracker.addImage(image, 0);
        try {
            mediaTracker.waitForAll();
        } catch (InterruptedException ie) {
        }

        size =
            maxinside(
                new Dimension(image.getWidth(null), image.getHeight(null)),
                size);

        image =
            image.getScaledInstance(
                size.width,
                size.height,
                Image.SCALE_SMOOTH);

        mediaTracker.addImage(image, 0);
        try {
            mediaTracker.waitForAll();
        } catch (InterruptedException ie) {
        }

        add(new JLabel(path));
        setVisible(true);
    }

    public void paint(java.awt.Graphics g) {
        Graphics2D graphics2D = (Graphics2D) g;
        int width = getWidth() - image.getWidth(null);
        int height = getHeight() - image.getHeight(null);
        graphics2D.drawImage(image, width / 2, height / 2, this);
    }

    public Dimension maxinside(Dimension source, Dimension target) {
        double widthfactor = (double) target.width / source.width;
        double heightfactor = (double) target.height / source.height;

        double factor;
        if (widthfactor < heightfactor)
            factor = widthfactor;
        else
            factor = heightfactor;

        int width = (int) Math.round(source.width * factor);
        int height = (int) Math.round(source.height * factor);

        return new Dimension(width, height);
    }
}
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester