雖然在JavaFx中,ImageView跟Image物件支援Gif,但是相容性好像不怎麼好,試了5張只有1張能動。
研究了一下發現有Gif的解碼器套件,雖然有點麻煩,但手動處理後相容性好多了,也比較能控制(例如:暫停播放)。
大致上的流程為:
- 使用套件解碼Gif成多張圖片。
- 將圖片放進陣列。
- 紀錄圖片間格。
- 建立一個Timer,輪播圖片。
實作部分:
1.在pom.xml
導入解碼套件:
<dependency> <groupId>com.github.zh79325</groupId> <artifactId>open-gif</artifactId> <version>1.0.4</version> </dependency>
2.讀入Gif檔,並解碼放進陣列
此範例是將Gif作為背景使用,所以比較多轉換過程。
實際上要在ImageView
中顯示的話,只要轉成Image
即可,不用這麼麻煩轉成Background
格式。
private void reloadGifBackground1(){ //讀入Gif File File bg = new File(fsv.getHomeDirectory() + "giphy.gif"); try{ final FileInputStream data = new FileInputStream(bg.getAbsolutePath()); //使用GifDecoder解碼 final GifDecoder.GifImage gif = GifDecoder.read(data); //圖片寬高,如果需要的話 final int width = gif.getWidth(); final int height = gif.getHeight(); //影格總數 final int frameCount = gif.getFrameCount(); //存放每個影格的圖片(這邊要放在背景所以才用Background格式,一般存成Image格式即可) Background[] bgArray = new Background[frameCount]; //影格的時間,可以統一儲存也可以存進陣列,看圖片 int delay = 0; //開始讀取影格 for (int i = 0; i < frameCount; i++) { final BufferedImage img = gif.getFrame(i); //轉換圖檔並存入陣列 Image im = SwingFXUtils.toFXImage(img, null); bgArray[i] = new Background(new BackgroundImage(im, BackgroundRepeat.NO_REPEAT, BackgroundRepeat.NO_REPEAT, BackgroundPosition.CENTER, BackgroundSize.DEFAULT)); delay = gif.getDelay(i); } //播放 playGifToBackground1(delay, bgArray, frameCount); } catch (IOException e) { e.printStackTrace(); } }
3.使用Timer播放Gif
playGifToBackground1
private int gifBackgroundIndex1 = 0;//gif目前的播放位置 private Timer gifToBackgroundTimer1 = null; /** * 播放gif * @param speed 解檔gif中的速度 * @param bg 轉換過的背景陣列 * @param count 圖片數 */ private void playGifToBackground1(long speed, Background[] bg, int count){ //每當重新呼叫時,重設(播放新圖片) gifBackgroundIndex1 = 0; gifToBackgroundTimer1 = null; gifToBackgroundTimer1 = new Timer(); gifToBackgroundTimer1.schedule(new TimerTask() { public void run() { Platform.runLater(() -> { aptest.setBackground(bg[gifBackgroundIndex1]); }); //往下一個影格播放,如果到底了就重播 if(gifBackgroundIndex1 < count-1){ gifBackgroundIndex1++; }else{ gifBackgroundIndex1 = 0; } } }, 0, speed*10); }
因為是使用Timer,所以最後離開程式時,要記得關掉。
可以用一個boolean值,控制Gif的播放暫停。
speed速度的部分,不知道為什麼要*10才正確。
-END-
發佈留言