2013-10-10 5 views
0

Я прокручиваю несколько png для создания анимации для java-заставки.SplashScreen java change alpha

Я начала анимации с помощью этого

java -splash:images/anim.png SplashDemo 

и использовать PNGs внутри класса. Вы можете найти класс здесь- http://pastebin.com/UWm25QfY

Моя единственная проблема в том, что бы ни альфа я выбираю, чтобы начать анимацию с помощью anim.png является окончательным и переписывается для всех PNG файлов позже

Я попытался AlphaComposite.Clear, Src, SrcOver, но ничего не получилось. Если я загружаю png iniatically с 0 opacity, тогда вся анимация исчезает. Может ли кто-нибудь сказать мне, как избавиться от этого?

+0

ли связанный код только код, который вы используете, или вы изменили его? – MadProgrammer

+0

@MadProgrammer http://pastebin.com/UWm25QfY Я немного изменил извинения, я обновил сообщение –

ответ

1

Таким образом, проблема, с которой вы сталкиваетесь, связана с тем фактом, что контекст, который вы рисуете, никогда не «очищается» или «отдыхает» между обновлениями. Я знаю, что это боль, но вот оно.

О единственном выборе, который у вас есть, - это фактически сбросить выходные данные на каждом цикле, прежде чем рисовать следующее изображение.

Lucky for use, SplashScreen фактически предоставляет URL фоновому изображению. Это позволяет нам загружать изображение самостоятельно и перерисовывать на поверхности по мере необходимости.

Вы также должны приложить все усилия для восстановления контекста Graphics до состояния, в котором вы его нашли (за исключением того, что вы нарисовали на нем, конечно). Это может быть сделано eaisly, сделав копию графического состояния, прежде чем рисовать на ней ...

Graphics2D g2d = (Graphics2D)g.create(); 
// Do you're painting here... 
// Release the state when you're done. 
g2d.dispose(); 

enter image description here

import java.awt.AlphaComposite; 
import java.awt.Dimension; 
import java.awt.Frame; 
import java.awt.Graphics2D; 
import java.awt.GraphicsConfiguration; 
import java.awt.GraphicsDevice; 
import java.awt.GraphicsEnvironment; 
import java.awt.Image; 
import java.awt.SplashScreen; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.awt.event.WindowListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

import javax.imageio.ImageIO; 

public class SplashScreen100 extends Frame implements ActionListener { 

    static ArrayList<Image> imgs; 

    private static final long serialVersionUID = 1L; 
    private BufferedImage background; 

    protected void renderSplashFrame(Graphics2D g, Image bg) { 

     // Get the splash screen size... 
     Dimension size = SplashScreen.getSplashScreen().getSize(); 
     int width = size.width; 
     int height = size.height; 

     // Center the image within the splash screen 
     int x = (width - bg.getWidth(null))/2; 
     int y = (height - bg.getHeight(null))/2; 
     Graphics2D g2d = (Graphics2D) g.create(); 

     // Draw the background 
     g2d.drawImage(background, 0, 0, null); 
     // Apply alpha composite 
     g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f)); 
     // Draw the image... 
     g2d.drawImage(bg, x, y, null); 
     g2d.dispose(); 
    } 

    public SplashScreen100() { 
     super("SplashScreen demo"); 
     final SplashScreen splash = SplashScreen.getSplashScreen(); 
     if (splash == null) { 
      System.out.println("SplashScreen.getSplashScreen() returned null"); 
      return; 
     } 
     Graphics2D g = splash.createGraphics(); 
     if (g == null) { 
      System.out.println("g is null"); 
      return; 
     } 

     try { 
      background = ImageIO.read(splash.getImageURL()); 

      for (Image img : imgs) { 
       renderSplashFrame(g, img); 
       splash.update(); 
       // I put this in to slow the updates down... 
       try { 
        Thread.sleep(250); 
       } catch (InterruptedException ex) { 
        Logger.getLogger(SplashScreen100.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } catch (IOException exp) { 
      exp.printStackTrace(); 
     } 
     splash.close(); 
    } 

    public void actionPerformed(ActionEvent ae) { 
     System.exit(0); 
    } 

    public static void main(String args[]) { 
     System.setProperty("sun.java2d.opengl", "True"); 
     GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment(); 
     GraphicsDevice device = env.getDefaultScreenDevice(); 
     GraphicsConfiguration config = device.getDefaultConfiguration(); 

     imgs = new ArrayList<Image>(); 
     for (File file : new File("\path\to\images").listFiles()) { 
      if (file.getName().toLowerCase().endsWith(".png")) { 
       try { 
        Image buffy = ImageIO.read(file); 
        imgs.add(buffy); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     SplashScreen100 test = new SplashScreen100(); 
    } 

} 

Изменены с другим подходом

В принципе, как и размер изображения увеличивается, скорость обновления уменьшается. Вместо этого я просто создал бы свой собственный, чтобы вы могли лучше контролировать процесс обновления.

В качестве основного дисплея используется JWindow в качестве базового окна и настраиваемый JPanel.

enter image description here

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GraphicsConfiguration; 
import java.awt.GraphicsEnvironment; 
import java.awt.Image; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collections; 
import java.util.List; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import static splashscreen.MySplashScreen.createCompatibleImage; 
import static splashscreen.MySplashScreen.getGraphicsConfiguration; 

public class DifferentSplashScreen { 

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

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

       JWindow frame = new JWindow(); 
       frame.setAlwaysOnTop(true); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new SplashPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class SplashPane extends JPanel { 

     private BufferedImage background; 
     private List<BufferedImage> frames; 
     private int frameIndex; 
     private BufferedImage currentFrame; 

     public SplashPane() { 
      try { 
       background = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\MegaTokyo\\2005-09-29-3957.jpeg")); 
       frames = new ArrayList<>(40); 
       List<BufferedImage> images = new ArrayList<>(20); 
       for (int index = 0; index < 20; index++) { 
        try { 
         BufferedImage buffy = ImageIO.read(new File(index + ".png")); 
         images.add(createCompatibleImage(buffy)); 
        } catch (IOException e) { 
         e.printStackTrace(); 
        } 
       } 
       frames.addAll(images); 
       Collections.reverse(images); 
       frames.addAll(images); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
      final Timer timer = new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        if (frameIndex >= frames.size()) { 
         frameIndex = 0; 
        } 
        currentFrame = frames.get(frameIndex); 
        frameIndex++; 
        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight()); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (background != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       int x = (getWidth() - background.getWidth())/2; 
       int y = (getHeight() - background.getHeight())/2; 
       g2d.drawImage(background, x, y, this); 

       if (currentFrame != null) { 

        x = (getWidth() - currentFrame.getWidth())/2; 
        y = (getHeight() - currentFrame.getHeight())/2; 
        g2d.drawImage(currentFrame, x, y, this); 

       } 
       g2d.dispose(); 
      } 
     } 
    } 

    public static GraphicsConfiguration getGraphicsConfiguration() { 
     return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration(); 
    } 

    public static BufferedImage createCompatibleImage(BufferedImage master) { 
     BufferedImage img = createCompatibleImage(master, master.getWidth(), master.getHeight()); 
     Graphics2D g2d = img.createGraphics(); 
     g2d.drawImage(master, 0, 0, null); 
     g2d.dispose(); 
     return img; 
    } 

    public static BufferedImage createCompatibleImage(BufferedImage image, 
      int width, int height) { 
     return getGraphicsConfiguration().createCompatibleImage(width, height, image.getTransparency()); 
    } 
} 

Он также преобразует все изображения в «устройство несовместимы» изображения, то есть они должны оказывать быстрее, так как не нужно конвертировать на лета их цвет паллетные лет.

Фоновое изображение было 1563x1250, а изображения лиц 300x300 (с различными уровнями альфа).

Используйте этот пример, я получил стабильно обновлять без проблем, используя одни и те же изображения с SplashScreen, это было довольно ужасно ...

+0

Не будет ли это испортить частоту кадров?Я попробую это tomoro –

+0

Какая частота кадров? – MadProgrammer

+0

Когда я перебираю изображения, частота кадров, которую я получаю, иногда падает. Любые предложения по улучшению частоты кадров. Я думаю, что вы решили альфа-проблему, спасибо большое –