Java淡入淡出图像 [英] Java fade in and out of images

查看:31
本文介绍了Java淡入淡出图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试学习如何将图像淡入和淡出到另一个图像或从另一个图像中.因此,如果我有 2 张图像,并且目前正在显示 1 张图像,我想在背景中显示另一张图像并将第一张图像淡入第二张图像.或者,我想将焦点设置在新图像上并在第一个图像上慢慢淡入,然后停止显示第一个图像.

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. 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.

我不确定如何:

  1. 设置焦点,如果需要的话.

  1. to set focus, if even needed.

如果我将 alpha 更改为 0 并递增并且只绘制一张图像,我可以淡入,但是我无法使用此代码的任何变体使其淡出.(即注释掉要绘制的一张图像).

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. (i.e. commenting out one image to draw).

真的,我担心的是能够拥有 2 张图像并使当前显示的图像慢慢消失在第二张图像中.这是如何完成的并不需要与此有关.

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. 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();
    }
}

推荐答案

基本上,这样做是使用相同的 alpha 值,从 0-1 淡入,然后使用相同的 alpha,从 1-0 开始,允许两个图像交叉淡入淡出...

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...

魔法基本上发生在 paintComponent 中,其中图像使用 alpha 值传入,而传出图像使用 1f - alpha.

The magic basically, happens in the paintComponent, where the image coming in using the alpha value and the outgoing image uses 1f - alpha.

在两个图像之间切换实际上是一个相同的过程,期望将 inImage 替换为 outImage

Switching between the two images is actually a the same process, expect the inImage is swapped for the outImage

时间有点不同.它不是使用标准增量(例如 0.01)从 0-1 直接移动,而是使用基于时间的算法.

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.

也就是说,我使用一个计时器,它每 40 毫秒左右滴答一次,然后根据计时器运行的时间进行计算,并相应地计算 alpha 值...

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...

这允许您更改动画将花费的时间量,但也提供了一个稍微更好的算法,该算法考虑了 Swings 渲染引擎的被动性质...

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...

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();
        }

    }

}

这篇关于Java淡入淡出图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆