1. 程式人生 > >多媒體開發(10):提取圖片以及點陣圖儲存

多媒體開發(10):提取圖片以及點陣圖儲存

> 小白:提取視訊中的圖片嗎?那很簡單,播放視訊再截圖就行啦。 播放視訊再截圖的做法,當然可以。但是,手動截圖會太累而且無法保證準確度,特別是需要反覆提取圖片時,或者需要提取“105秒那一瞬間的美女圖片”時,或者我需要每秒出一張圖片時,那有別的辦法嗎? **本文介紹,如何使用FFmpeg實現從視訊中提取圖片的功能。** 一般使用FFmpeg的方式,有兩種,一種是使用FFmpeg的命令(也就是呼叫ffmpeg這個程式),另一種是呼叫FFmpeg的庫檔案。這裡小程同樣從命令列以及程式碼呼叫這兩種方式,進行介紹。 ### (一)使用FFmpeg命令來解決問題 在安裝FFmpeg後,打個命令就可以實現這個功能。對於FFmpeg的安裝或除錯,之前介紹過。 提取圖片可以這樣,比如: > ffmpeg -ss 00:00:5 -i moments.mp4 -vframes 1 -f image2 -y a.png 引數的意思是這樣的: ss表示開始提取圖片的時間點,既可以用時分秒格式,也可以是多少秒。 如果使用到這個引數,那應該把它作為第一個引數,因為可以讓FFmpeg提速。 i表示輸入檔案,就是視訊檔案。 vframes表示拿多少幀,也就是多少張圖片。注意,這個引數要放在-i引數之後。 f表示提取出來的圖片的格式。 y表示覆蓋已有同名的圖片。 再比如,可以這樣: > ffmpeg -i xxx.mp4 -r 1 -y -f image2 -t 5 -s 240*320 pc%3d.jpg 引數的意思是這樣的: r表示每秒提取圖片的幀數,即幀率,預設是25fps,上面設定為一秒拿一張圖。 t表現持續提取多少秒,也可以用時分秒的格式來表示。 s表出來的圖片的尺寸。 3%d表示以001、002這樣的格式來命名輸出的圖片。 於是, > 小白:那麼說,如果我發現視訊某個時間點有美女的話,那我就可以用ss從這個時間點再前一點,然後用t來持續提取5秒,或者用vframes來提取幾十張,那就準沒漏了!也就是這樣: > ffmpeg -ss 10 -t 5 -r 1 -i Movie-1.mp4 -f image2 -y pc-temp/image%3d.jpg > 小白:看,這是提取到的美女圖: ![提取的圖片](https://free-picture1.oss-cn-shenzhen.aliyuncs.com/%E5%A4%9A%E5%AA%92%E4%BD%93%E5%BC%80%E5%8F%91/ffmeg%E5%BA%94%E7%94%A8-%E4%BB%8E%E8%A7%86%E9%A2%91%E4%B8%AD%E6%8F%90%E5%8F%96%E5%9B%BE%E7%89%87/%E6%8F%90%E5%8F%96%E7%9A%84%E5%9B%BE%E7%89%871.jpeg) 另一方面,你在提取到若干成圖片後,有可能想把這些圖片編碼成視訊,這時同樣可以藉助FFmpeg命令來完成。需要注意,圖片變成視訊,是需要視訊編碼器的,所以在安裝FFmpeg時需要把視訊編碼器也帶上(比如x264),這個之前有所介紹。 把圖片編碼成視訊的命令是這樣的: > ffmpeg -f image2 -i img%3d.jpg test.mp4 img%d表示以"img001", "img002"這種命名的檔案(也就是之前提取出來的圖片),按順序使用。注意f引數要在i引數之前。 你可能覺得mp4格式沒有gif格式通用,於是又有了把mp4轉成gif動態圖的需求,這時還是可以敲打ffmpeg命令: > ffmpeg -i hello.mp4 hello.gif 當然這只是簡單地把mp4轉成gif,你也可以加上解析度、位元速率之類的引數來控制,這裡不細說。 ### (二)寫程式碼呼叫FFmpeg庫來解決問題 通過寫程式碼呼叫FFmpeg庫的方式來提取圖片,並且儲存成24bit的點陣圖。 小程先貼上演示程式碼,再在後面做一些解釋: ``` #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #