2013-10-10 3 views
0

나는 자바 스플래시 스크린을위한 애니메이션을 만들기 위해 몇 가지 png를 반복하고 있습니다.SplashScreen 자바 변경 알파

나는이

java -splash:images/anim.png SplashDemo 

를 사용하여 애니메이션을 시작하고 클래스 내부의 PNG 파일을 사용합니다. http://pastebin.com/UWm25QfY

내 유일한 문제는 내가 anim.png가 최종 사용하여 애니메이션을 시작하려면 무엇을 선택 알파이고 나는 AlphaComposite.Clear을 시도 나중에

모든 PNG 파일에 대해 덮어 쓰기되고 여기 - 당신은 클래스를 찾을 수 있습니다 Src, SrcOver하지만 아무 효과가 없습니다. 0 불투명도로 PNG를 자연스럽게로드하면 전체 애니메이션이 사라집니다. 아무도 이걸 없애는 방법을 말해 줄 수 있습니까?

+0

링크 된 코드를 사용하거나 당신이 그것을 변경 한 경우에만 코드가 ... 꽤 무서운 꾸준히 SplashScreen와 같은 이미지를 사용하여, 문제없이 업데이트하려면했다있어? – MadProgrammer

+0

@MadProgrammer http://pastebin.com/UWm25QfY 약간 죄송합니다. 게시글을 업데이트했습니다. –

답변

1

그래서 당신이 직면하고있는 문제는 그림을 그려야하는 Graphics 컨텍스트가 업데이트 사이에 실제로 "정리"되거나 "휴식"되지 않는다는 사실과 관련이 있습니다. 어느 것이 고통인지, 나도 안다.하지만 거기에있다.

당신이 가지고있는 유일한 선택은 다음 이미지를 칠하기 전에 실제로 각 사이클의 출력을 재설정하는 것입니다.

운 좋게도 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을 주 디스플레이로 사용합니다.

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

enter image description here

그것은 또한 빠르게 자신의 색 레트의이 즉석에서 변환 할 필요가 없기 때문에 렌더링해야 의미 모든 이미지에 "장치 compatiable"이미지를 변환합니다.

배경 이미지는 1563x1250이고 얼굴 이미지는 300x300 (알파 수준이 달라짐)입니다.

사용이 예, 나는, 그것은

+0

프레임 속도를 올릴 수 없을까요 ??나는 그것을 시도 할 것이다 tomoro –

+0

어떤 프레임 속도? – MadProgrammer

+0

이미지 위로 반복하면 프레임 레이트가 가끔 내려갑니다. 프레임 속도를 향상시키기위한 제안 사항. 알파 문제를 해결했다고 생각합니다. –