1. 程式人生 > >java從視訊中獲截幀生成靜態圖與GIF,圖片旋轉

java從視訊中獲截幀生成靜態圖與GIF,圖片旋轉

pom:

<!-- 視訊截圖 -->
<dependency>
	<groupId>org.bytedeco</groupId>
	<artifactId>javacv-platform</artifactId>
	<version>1.4.2</version>
</dependency>
<!-- gif -->
<dependency>
    <groupId>com.madgag</groupId>
    <artifactId>animated-gif-lib</artifactId>
    <version>1.4</version>
</dependency>
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;
 
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import com.madgag.gif.fmsware.AnimatedGifEncoder;
 
public class TestMain {
	/**
	 * 擷取視訊指定幀生成gif
	 * @param videofile 視訊檔案
	 * @param startFrame 開始幀
	 * @param frameCount 擷取幀數
	 * @param frameRate 幀頻率(預設:3)
	 * @param margin 每擷取一次跳過多少幀(預設:3)
	 * @throws IOException 擷取的長度超過視訊長度
	 */
	public static void buildGif(String videofile,int startFrame,int frameCount,Integer frameRate,Integer margin) throws IOException {
		if(margin==null)margin=3;
		if(frameRate==null)frameRate=3;
		FileOutputStream targetFile = new FileOutputStream(videofile.substring(0,videofile.lastIndexOf("."))+".gif");
		FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
		Java2DFrameConverter converter = new Java2DFrameConverter();
	    ff.start();
	    try {
	    	if(startFrame>ff.getLengthInFrames() & (startFrame+frameCount)>ff.getLengthInFrames()) {
	    		throw new RuntimeException("視訊太短了");
	    	}
			ff.setFrameNumber(startFrame);
			AnimatedGifEncoder en = new AnimatedGifEncoder();
		    en.setFrameRate(frameRate);
		    en.start(targetFile);
		    for(int i=0;i<frameCount;i++) {
		    	en.addFrame(converter.convert(ff.grab()));
		    	ff.setFrameNumber(ff.getFrameNumber()+margin);
		    }
		    en.finish();
		}finally {
			ff.stop();
			ff.close();
		}
	}
	/**
	 * 將圖片旋轉指定度
	 * @param bufferedimage 圖片
	 * @param degree 旋轉角度
	 * @return
	 */
	 public static BufferedImage rotateImage(BufferedImage bufferedimage,int degree){
			 int w= bufferedimage.getWidth();// 得到圖片寬度。
			 int h= bufferedimage.getHeight();// 得到圖片高度。
			 int type= bufferedimage.getColorModel().getTransparency();// 得到圖片透明度。
			 BufferedImage img;// 空的圖片。
			 Graphics2D graphics2d;// 空的畫筆。
			 (graphics2d= (img= new BufferedImage(w, h, type))
			 .createGraphics()).setRenderingHint(
			 RenderingHints.KEY_INTERPOLATION,
			 RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			 graphics2d.rotate(Math.toRadians(degree), w / 2, h / 2);// 旋轉,degree是整型,度數,比如垂直90度。
			 graphics2d.drawImage(bufferedimage, 0, 0, null);// 從bufferedimagecopy圖片至img,0,0是img的座標。
			 graphics2d.dispose();
			 return img;// 返回複製好的圖片,原圖片依然沒有變,沒有旋轉,下次還可以使用。
	}
	
	 /**
	  * 擷取視訊指定幀儲存為指定格式的圖片(圖片儲存在視訊同文件夾下)
	  * @param videofile 視訊地址
	  * @param imgSuffix 圖片格式
	  * @param indexFrame 第幾幀(預設:5)
	  * @throws Exception
	  */
	public static void fetchFrame(String videofile,String imgSuffix,Integer indexFrame)throws Exception {
		if(indexFrame==null)indexFrame=5;
	    FFmpegFrameGrabber ff = new FFmpegFrameGrabber(videofile);
	    ff.start();
	    try {
			int lenght = ff.getLengthInFrames();
			int i = 0;
			Frame f = null;
			while (i < lenght) {
			    f = ff.grabFrame();
			    if ((i > indexFrame) && (f.image != null)) {
			        break;
			    }
			    i++;
			}
			int owidth = f.imageWidth ;
			int oheight = f.imageHeight ;
			int width = 800;
			int height = (int) (((double) width / owidth) * oheight);
			Java2DFrameConverter converter =new Java2DFrameConverter();
			BufferedImage fecthedImage =converter.getBufferedImage(f);
			BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
			bi.getGraphics().drawImage(fecthedImage.getScaledInstance(width, height, Image.SCALE_SMOOTH),
			        0, 0, null);
			bi=rotateImage(bi, 90);
			File targetFile = new File(videofile.substring(0,videofile.lastIndexOf("."))+imgSuffix);
			ImageIO.write(bi, "jpg", targetFile);
		}finally {
			ff.stop();
			ff.close();
		}
	}
 
	public static void main(String[] args) {
		try {
			//fetchFrame("D:\\test\\QQ.mp4",".jpg",10);
			buildGif("D:\\test\\QQ.mp4", 5, 20, 3,3);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}