雖然在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-
發佈留言