简体   繁体   English

Java淡入淡出图像

[英]Java fade in and out of images

I am trying to learn how to fade in and out images into another image or from another image.我正在尝试学习如何将图像淡入和淡出到另一个图像或从另一个图像中。 So, if I have 2 images, and 1 is being displayed at the moment, I want to display another image in the background and fade the first image out into the 2nd image.因此,如果我有 2 张图像,并且目前正在显示 1 张图像,我想在背景中显示另一张图像并将第一张图像淡入第二张图像。 OR, I want to set the focus on the new image and slowly fade it in over the 1st image, then stop displaying the 1st one.或者,我想将焦点设置在新图像上并在第一个图像上慢慢淡入,然后停止显示第一个图像。

I'm not sure how:我不确定如何:

  1. to set focus, if even needed.设置焦点,如果甚至需要。

  2. I can fade in if I change the alpha to 0 and increment up and only draw one image, however I cannot get it to fade out either with any variation of this code.如果我将 alpha 更改为 0 并递增并且只绘制一张图像,我可以淡入,但是我无法使用此代码的任何变体使其淡出。 (ie commenting out one image to draw). (即注释掉一张要绘制的图像)。

Edit: Really, all I'm worried about is being able to have 2 images and make the image currently being displayed slowly disappear into the 2nd image.编辑:真的,我担心的是能够拥有 2 张图像并使当前显示的图像慢慢消失在第二张图像中。 How that is accomplished doesn't need to be with this.这是如何完成的并不需要与此有关。

Here is a code sample I'm messing with:这是我弄乱的代码示例:

import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class FadeIn extends JPanel implements ActionListener {

    private Image imagem;
    private Image image2;
    private Timer timer;
    private float alpha = 1f;

    public FadeIn() {
        imagem = (new ImageIcon(getClass().getResource(
             "/resources/1stImage.jpg"))).getImage();
        image2 = (new ImageIcon(getClass().getResource(
             "/resources/2ndImage.jpg"))).getImage();    
        timer = new Timer(20, this);
        timer.start();
    }
    // here you define alpha 0f to 1f

    public FadeIn(float alpha) {
        imagem = (new ImageIcon(getClass().getResource(
             "/resources/1stImage.jpg"))).getImage();
        this.alpha = alpha;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.drawImage(imagem, 0, 0, 400, 300, null);
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
                alpha));
        g2d.drawImage(image2, 0, 0, 400, 300, null);
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Fade out");
        frame.add(new FadeIn());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(420, 330);
        // frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        alpha += -0.01f;
        if (alpha <= 0) {
            alpha = 0;
            timer.stop();
        }
        repaint();
    }
}

Basically, what this does is use the same alpha value, fading in from 0-1 and then using the same alpha, going from 1-0, allowing the two images to cross fade over each other...基本上,这样做是使用相同的 alpha 值,从 0-1 淡入,然后使用相同的 alpha,从 1-0 开始,允许两个图像相互淡入淡出......

褪色

The magic basically, happens in the paintComponent , where the image coming in using the alpha value and the outgoing image uses 1f - alpha .魔法基本上发生在paintComponent ,其中使用alpha值传入的图像和传出图像使用1f - alpha

Switching between the two images is actually a the same process, expect the inImage is swapped for the outImage在两个图像之间切换实际上是一个相同的过程,期望将inImage交换为outImage

The timing is little different.时间略有不同。 Instead of a straight move from 0-1 using a standard delta (ie 0.01 for example), this uses a time based algorithm.这不是使用标准增量(例如0.01 )从0-1的直线移动,而是使用基于时间的算法。

That is, I use a timer which ticks every 40 milliseconds or so, it then does a calculation based on the amount of time the timer has being running and calculates the alpha value accordingly...也就是说,我使用一个计时器,它每 40 毫秒左右滴答一次,然后根据计时器运行的时间进行计算,并相应地计算alpha值......

This allows you to change the amount of time the animation will take, but also provides a slightly better algorithm that takes into account the passive nature of Swings rendering engine...这允许您更改动画将花费的时间量,但也提供了一个稍微更好的算法,该算法考虑了 Swings 渲染引擎的被动性质......

import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class FadeImage {

    public static void main(String[] args) {
        new FadeImage();
    }

    public FadeImage() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        public static final long RUNNING_TIME = 2000;

        private BufferedImage inImage;
        private BufferedImage outImage;

        private float alpha = 0f;
        private long startTime = -1;

        public TestPane() {
            try {
                inImage = ImageIO.read(new File("/path/to/inImage"));
                outImage = ImageIO.read(new File("/path/to/outImage"));
            } catch (IOException exp) {
                exp.printStackTrace();
            }

            final Timer timer = new Timer(40, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (startTime < 0) {
                        startTime = System.currentTimeMillis();
                    } else {

                        long time = System.currentTimeMillis();
                        long duration = time - startTime;
                        if (duration >= RUNNING_TIME) {
                            startTime = -1;
                            ((Timer) e.getSource()).stop();
                            alpha = 0f;
                        } else {
                            alpha = 1f - ((float) duration / (float) RUNNING_TIME);
                        }
                        repaint();
                    }
                }
            });
            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    alpha = 0f;
                    BufferedImage tmp = inImage;
                    inImage = outImage;
                    outImage = tmp;
                    timer.start();
                }

            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(
                            Math.max(inImage.getWidth(), outImage.getWidth()), 
                            Math.max(inImage.getHeight(), outImage.getHeight()));
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
            int x = (getWidth() - inImage.getWidth()) / 2;
            int y = (getHeight() - inImage.getHeight()) / 2;
            g2d.drawImage(inImage, x, y, this);

            g2d.setComposite(AlphaComposite.SrcOver.derive(1f - alpha));
            x = (getWidth() - outImage.getWidth()) / 2;
            y = (getHeight() - outImage.getHeight()) / 2;
            g2d.drawImage(outImage, x, y, this);
            g2d.dispose();
        }

    }

}

This is a easy and short most developers using java code for image fade.这是大多数开发人员使用 java 代码进行图像淡入淡出的简单而简短的方法。

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 *
 * @author ADMIN
 */
public class ImageFade extends JFrame {

    ImageFade() {
        setLayout(null);

        JLabel l = new JLabel();
        l.setBounds(0, 0, 100, 96);
        add(l);

        Thread tp = new Thread() {
            @Override
            public void run() {
                for (int amp = 0; amp <= 500; amp++) {
                    try {
                        sleep(1);
                        try {
                            BufferedImage bim = ImageIO.read(new File("src/image/fade/image.png"));
                            BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB);
                            Graphics2D createGraphics = nbim.createGraphics();
                            createGraphics.drawImage(bim, null, 0, 0);
                            RescaleOp r = new RescaleOp(new float[]{1f, 1f, 1f, (float) amp / 500}, new float[]{0, 0, 0, 0}, null);
                            BufferedImage filter = r.filter(nbim, null);
                            l.setIcon(new ImageIcon(filter));
                        } catch (Exception ex) {
                            System.err.println(ex);
                        }
                    } catch (InterruptedException ex) {
                    }
                }
            }
        };
        tp.start();

        setUndecorated(true);
        setBackground(new Color(0, 0, 0, 0));
        setSize(100, 96);
        setVisible(true);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        setAlwaysOnTop(true);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        ImageFade fr = new ImageFade();
    }
}

in this code you can see a thread code.在此代码中,您可以看到线程代码。 in the thread this image will fade in.在这个图像将淡入的线程中。

the used image is stack overflow web page's logo image.使用的图像是堆栈溢出网页的徽标图像。

only by shown code the image will fade in.只有通过显示的代码图像才会淡入。

Thread tp = new Thread() {
    @Override
    public void run() {
        for (int amp = 0; amp <= 500; amp++) {
            try {
                sleep(1);
                try {
                    BufferedImage bim = ImageIO.read(new File("src/image/fade/image.png"));
                    BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB);
                    Graphics2D createGraphics = nbim.createGraphics();
                    createGraphics.drawImage(bim, null, 0, 0);
                    RescaleOp r = new RescaleOp(new float[]{1f, 1f, 1f, (float) amp / 500}, new float[]{0, 0, 0, 0}, null);
                    BufferedImage filter = r.filter(nbim, null);
                    l.setIcon(new ImageIcon(filter));
                } catch (Exception ex) {
                      System.err.println(ex);
                  }
            } catch (InterruptedException ex) {
            }
        }
    }
};
tp.start();

This code is very simple to use.这段代码使用起来非常简单。

This is not from any book, internet or etc. It is developed by me.这不是来自任何书籍、互联网等。它是由我开发的。

A normal image is not able to change alpha.普通图像无法更改 alpha。 By code : BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB);通过代码: BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB); the image will convert to ARGB - Alpha, Red, Green, Blue (R,G,B,A) image.图像将转换为 ARGB - Alpha、红色、绿色、蓝色(R、G、B、A)图像。

So you can change the alpha of a image.因此,您可以更改图像的 alpha。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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