【JAVA】 后端 圖片裁剪锁右、壓縮 及 視頻壓縮

本人使用java封裝的后端媒體處理工具包

基于ImageMagick和FFmpeg客戶端汁咏,使用java調(diào)用命令行實現(xiàn)
https://gitee.com/gnliscream/multimedia-utils

介紹

java后端的圖片莲趣、視頻處理工具jar包

1.獲取視頻信息

2.生成視頻封面圖

3.異步壓縮視頻(生成輸出文件名后虑啤,調(diào)用異步壓縮視頻方法隙弛,且同一時間只會處理一個視頻,多個請求的視頻會進行排隊處理)

4.異步壓縮視頻完成時回調(diào)通知

5.圖片裁切

6.圖片壓縮

客戶端安裝

運行環(huán)境需安裝FFmpeg和ImageMagick狞山,官網(wǎng)地址如下:

FFmpeg:https://ffmpeg.org/

ImageMagick:http://www.imagemagick.com.cn/

FFmpeg解壓后需設置/bin目錄的環(huán)境變量全闷,ImageMagick安裝版安裝后會自動設置環(huán)境變量。

引入依賴

<dependency>
      <groupId>com.whty.zdxt</groupId>
      <artifactId>multimedia-utils</artifactId>
      <version>0.0.1-SNAPSHOT</version>
</dependency>

配置

yml 配置上傳文件的臨時路徑

spring:
  servlet:
    multipart:
      # 是否支持 multipart 上傳文件
      enabled: true
      # 最大支持文件大小
      max-file-size: 10MB
      # 最大支持請求大小
      max-request-size: 10MB
      # 上傳文件的臨時目錄
      location: E:/tomcat-temp

注入 視頻處理類FFmpegUtils 以及 圖片處理類 ImageMagickUtils

import com.whty.zdxt.multimedia.util.FFmpegUtils;
import com.whty.zdxt.multimedia.util.ImageMagickUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class MultimediaUtilsConfig {
    
    /**
     * 視頻處理工具萍启,因為所有壓縮任務需要排隊進行总珠,所以FFmpegUtils需要是單例的,F(xiàn)FmpegUtils實例交由spring管理就為單例的
     */
    @Bean
    public FFmpegUtils fFmpegUtilsImpl() {
        return new FFmpegUtils();
    }

    /**
     * 圖片處理工具
     */
    @Bean
    public ImageMagickUtils imageMagickUtils() {
        return new ImageMagickUtils();
    }

}

使用

FileController

import com.example.demo.util.FileUtil;
import com.whty.zdxt.multimedia.attribute.CompressionAttributes;
import com.whty.zdxt.multimedia.attribute.CropAttributes;
import com.whty.zdxt.multimedia.attribute.ResizeAttributes;
import com.whty.zdxt.multimedia.attribute.VideoAttributes;
import com.whty.zdxt.multimedia.enumeration.Suffix;
import com.whty.zdxt.multimedia.enumeration.VideoSize;
import com.whty.zdxt.multimedia.pojo.FFmpegInfo;
import com.whty.zdxt.multimedia.util.FFmpegUtils;
import com.whty.zdxt.multimedia.util.ImageMagickUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.servlet.MultipartProperties;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

@RestController
@RequestMapping("/file")
public class FileController {

    @Autowired
    private FFmpegUtils fFmpegUtils;

    @Autowired
    private MultipartProperties multipartProperties;

    @Autowired
    private ImageMagickUtils imageMagickUtils;

    /**
     * 獲取視頻信息
     */
    @PostMapping("/getVideoInfo")
    public Object getFileInfo(@RequestParam MultipartFile file) {
        String location = multipartProperties.getLocation();

        // 生成上傳視頻的臨時文件
        File inputFile = FileUtil.multipartFile2File(file, location);

        // 調(diào)用視頻處理工具類
        String inputFileName = inputFile.getName();
        FFmpegInfo info = fFmpegUtils.getInfo(location, inputFileName);

        // 刪除上傳視頻的臨時文件
        inputFile.delete();
        return info;
    }

    /**
     * 生成視頻封面圖
     */
    @PostMapping("/createVideoCover")
    public Object createVideoCover(@RequestParam MultipartFile file) {
        String location = multipartProperties.getLocation();
        // 生成上傳視頻的臨時文件
        File inputFile = FileUtil.multipartFile2File(file, location);

        // 調(diào)用視頻處理工具類
        String outputFileName = fFmpegUtils.createCover(location, inputFile.getName());

        // 刪除上傳視頻的臨時文件
        inputFile.delete();
        return outputFileName;
    }

    /**
     * 壓縮視頻
     */
    @PostMapping("/compressionVideo")
    public Object compressionVideo(@RequestParam MultipartFile file) {

        String location = multipartProperties.getLocation();

        // 生成上傳視頻的臨時文件
        File inputFile = FileUtil.multipartFile2File(file, location);

        // 調(diào)用視頻處理工具類


        CompressionAttributes compressionAttributes = new CompressionAttributes();
        // 設置視頻壓縮完成時的回調(diào)URL
        compressionAttributes.setProgressUrl("http://localhost:8999/file/callback?fileId=111111&a=456");

        // 設置視頻壓縮參數(shù)
        VideoAttributes videoAttributes = new VideoAttributes();
        videoAttributes.setMaxDuration(15);
        videoAttributes.setMaxFps(20);
        videoAttributes.setVideoSize(VideoSize.HD480);

        compressionAttributes.setVideoAttributes(videoAttributes);

        String outputFileName = fFmpegUtils.putCompressionTask(location, inputFile.getName(), compressionAttributes);

        return outputFileName;
    }

    /**
     * 壓縮視頻完成時的回調(diào)
     */
    @PostMapping("/callback")
    public Object callback(@RequestBody String info, @RequestParam("fileId") String fileId, @RequestParam("a") String a) {
        // 回調(diào)信息
        String[] split = info.split("/");

        // 回調(diào)參數(shù) fileId勘纯,根據(jù)fileId查詢數(shù)據(jù)庫的上傳臨時文件名和下載臨時文件名局服,進行文件上傳和文件刪除
        System.out.println(String.format("fileId為%s的文件已壓縮完成", fileId));

        return null;
    }

    /**
     * 圖片裁切
     */
    @PostMapping("/crop")
    public Object crop(@RequestParam MultipartFile file) {

        String location = multipartProperties.getLocation();

        // 生成上傳圖片的臨時文件
        File inputFile = FileUtil.multipartFile2File(file, location);

        // 調(diào)用圖片處理工具類
        // 裁切成3000x1200的圖后,修改分辨率為寬800的圖(高度按比例縮胁底瘛)
        CropAttributes cropAttributes = new CropAttributes(3000, 1200, 1000, 500);
        ResizeAttributes resizeAttributes = new ResizeAttributes(800, null);
        String outputFileName = imageMagickUtils.cropAndResize(location, inputFile.getName(), cropAttributes, resizeAttributes);

        // 刪除上傳圖片的臨時文件
        inputFile.delete();
        return outputFileName;
    }

    /**
     * 圖片分辨率修改
     */
    @PostMapping("/resize")
    public Object resize(@RequestParam MultipartFile file) {

        String location = multipartProperties.getLocation();

        // 生成上傳圖片的臨時文件
        File inputFile = FileUtil.multipartFile2File(file, location);

        // 調(diào)用圖片處理工具類
        ResizeAttributes resizeAttributes = new ResizeAttributes(800, null);
        String outputFileName = imageMagickUtils.resize(location, inputFile.getName(), resizeAttributes, Suffix.JPG);

        // 刪除上傳圖片的臨時文件
        inputFile.delete();
        return outputFileName;
    }

}

FileUtil

import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.UUID;

public class FileUtil {

    /**
     * 將上傳的MultipartFile轉(zhuǎn)化為File
     */
    public static File multipartFile2File(MultipartFile multipartFile, String directory) {
        String suffix = getSuffix(multipartFile.getOriginalFilename());
        File tempFile = null;
        try {
            tempFile = new File(directory + "/" + UUID.randomUUID().toString() + suffix);
            multipartFile.transferTo(tempFile);
        } catch (IOException e) {
            throw new RuntimeException("multipartFile轉(zhuǎn)File失敗", e);
        }
        return tempFile;
    }

    /**
     * 獲取文件拓展名
     */
    public static String getSuffix(String fileName) {
        if (fileName == null) {
            throw new RuntimeException("獲取文件拓展名失敗");
        }
        int index = fileName.lastIndexOf(".");
        if (-1 == index) {
            throw new RuntimeException("獲取文件拓展名失敗");
        }
        return fileName.substring(index);
    }

}

文檔

圖片工具ImageMagickUtils

方法

1.圖片裁切后修改分辨率并指定輸出文件格式

cropAndResize(tempDirectory,inputFileName,cropAttributes,resizeAttributes,outputFileSuffix)

2.圖片裁切后修改分辨率

cropAndResize(tempDirectory,inputFileName,cropAttributes,resizeAttributes)

3.圖片裁切并指定輸出文件格式

crop(tempDirectory,inputFileName,cropAttributes,outputFileSuffix)

4.圖片裁切

crop(tempDirectory,inputFileName,cropAttributes)

5.圖片修改分辨率并指定輸出文件格式

resize(tempDirectory,inputFileName,resizeAttributes,outputFileSuffix)

6.圖片修改分辨率

resize(tempDirectory,inputFileName,resizeAttributes)

參數(shù)介紹

輸入?yún)?shù)
參數(shù) 類型 必需 注釋
tempDirectory String 臨時文件目錄
inputFileName String 輸入文件名
cropAttributes CropAttributes 裁切參數(shù)
resizeAttributes ResizeAttributes 修改分辨率參數(shù)
outputFileSuffix Suffix 輸出文件格式淫奔,未設置則同輸入文件格式

其中:

CropAttributes

參數(shù) 類型 必需 注釋
width Integer 裁切圖片的寬
height Integer 裁切圖片的高
leftOffset Integer 距左邊偏移量
topOffset Integer 距頂部偏移量

ResizeAttributes

參數(shù) 類型 必需 注釋
width Integer 輸出圖片的寬,只填寫寬則高自適應
height Integer 輸出圖片的高堤结,只填寫高則寬自適應
quality Integer 輸出圖片的質(zhì)量唆迁,范圍0~100,默認100
輸出參數(shù)
參數(shù) 類型 必需 注釋
outputFileName String 輸出文件名

視頻工具FFmpegUtils

方法

1.獲取視頻信息

getInfo(tempDirectory,inputFileName)

輸入?yún)?shù)
參數(shù) 類型 必需 注釋
tempDirectory String 臨時文件目錄
inputFileName String 輸入文件名
輸出參數(shù)
參數(shù) 類型 必需 注釋
format FFFormat 文件信息
videoInfo VideoInfo 視頻信息
audioInfo AudioInfo 音頻信息

其中:

FFFormat

參數(shù) 類型 必需 注釋
filename String 文件名全路徑名
duration String 文件時長
size String 文件大小
bitRate String 文件比特率

VideoInfo

參數(shù) 類型 必需 注釋
codecName String 視頻 編碼名稱
codecType String 類型 video
width Integer 視頻 寬度
height Integer 視頻 高度
frameRate Integer 視頻 幀率
duration Integer 視頻 時長
bitRate Integer 視頻 比特率
nbFrames Integer 視頻 總幀數(shù)

AudioInfo

參數(shù) 類型 必需 注釋
codecName String 音頻 編碼名稱
codecType String 類型 audio
duration Integer 音頻 時長
bitRate Integer 音頻 比特率
sampleRate Integer 音頻 采樣率
channels Integer 音頻 聲道數(shù) 1:單聲道 2:雙聲道
2.截取視頻封面

createCover(tempDirectory, inputFileName, outputFileSuffix)

createCover(tempDirectory, inputFileName)

輸入?yún)?shù)
參數(shù) 類型 必需 注釋
tempDirectory String 臨時文件目錄
inputFileName String 輸入文件名
outputFileSuffix Suffix 輸出文件格式竞穷,默認jpg
輸出參數(shù)
參數(shù) 類型 必需 注釋
outputFileName String 輸出文件名
3.視頻壓縮

putCompressionTask(tempDirectory, inputFileName, compressionAttributes)

putCompressionTask(tempDirectory, inputFileName, compressionAttributes, outputFileName)

輸入?yún)?shù)
參數(shù) 類型 必需 注釋
tempDirectory String 臨時文件目錄
inputFileName String 輸入文件名
compressionAttributes CompressionAttributes 壓縮參數(shù)
outputFileName String 輸出文件名唐责,默認UUID生成

其中:

CompressionAttributes

參數(shù) 類型 必需 注釋
videoAttributes VideoAttributes 視頻壓縮參數(shù)
audioAttributes AudioAttributes 音頻壓縮參數(shù)
progressUrl String 壓縮完成后的回調(diào)地址

VideoAttributes

參數(shù) 類型 必需 注釋
codec VideoCodec 視頻編碼(默認libx264,libx265)
maxFps Integer 最大幀率
videoSize VideoSize 視頻分辨率(hd480瘾带,hd720鼠哥,hd1080,800x800)
maxDuration Integer 最大時長
maxBitRate Integer 視頻最大比特率

AudioAttributes

參數(shù) 類型 必需 注釋
maxBitRate Integer 音頻最大比特率
maxSamplingRate Integer 音頻最大采樣率
輸出參數(shù)
參數(shù) 類型 必需 注釋
outputFileName String 輸出文件名

ImageMagick官網(wǎng)

http://www.imagemagick.com.cn/

命令行

圖片裁切

magick 1.jpg -crop 3000x1200+1000+500 2.jpg

1.jpg 為6000x4500的圖片

3000x1200 裁切后圖片的寬x高

+1000 裁切橫坐標偏移量

+500 裁切縱坐標偏移量

2.jpg 為裁切后的3000x1200的圖片

image

圖片壓縮

指定分辨率壓縮
magick 1.jpg -resize 3000x2250 2.jpg
給定寬度,高度自動選擇以保留寬高比肴盏。
magick 1.jpg -resize 3000 2.jpg
給定高度科盛,自動選擇寬度以保留寬高比。
magick 1.jpg -resize x2250 2.jpg

FFmpeg官網(wǎng)

https://ffmpeg.org/ffmpeg.html#Advanced-options

命令行

查詢視頻信息

ffprobe -v quiet -print_format json -show_format -show_streams 1.mp4

設置幀率 -r

ffmpeg –i input.mp4 –r fps output.mp4

設置碼率 音頻:-b:a 視頻: - b:v

ffmpeg -i input.avi -b:v 1500k output.mp4

設置分辨率

ffmpeg -i input.mp4 -s 320x240 output.mp4

設置聲道和采樣率

-ac 1 設置聲道數(shù)為1
-ar 48000 設置采樣率為48000Hz

截取視頻生成圖片

從第-ss秒開始菜皂,每秒截取-r張圖片贞绵,持續(xù)-t秒,使用-s進行縮放恍飘,保存為foo-001.jpeg, foo-002.jpeg...
ffmpeg -i 1.mp4 -ss 5 -r 1 -t 1 -s hd480 -f image2 foo-%03d.jpeg

網(wǎng)上的開源框架

https://github.com/a-schild/jave2

網(wǎng)上的相關資料

http://www.reibang.com/p/e14bc2551cfd
http://www.reibang.com/p/3c8c4a892f3c
https://blog.csdn.net/u010629285/article/details/102998555

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末榨崩,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子章母,更是在濱河造成了極大的恐慌母蛛,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件乳怎,死亡現(xiàn)場離奇詭異彩郊,居然都是意外死亡,警方通過查閱死者的電腦和手機蚪缀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進店門秫逝,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人询枚,你說我怎么就攤上這事违帆。” “怎么了金蜀?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵刷后,是天一觀的道長。 經(jīng)常有香客問我渊抄,道長尝胆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任护桦,我火速辦了婚禮含衔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嘶炭。我一直安慰自己抱慌,他們只是感情好逊桦,可當我...
    茶點故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布眨猎。 她就那樣靜靜地躺著,像睡著了一般强经。 火紅的嫁衣襯著肌膚如雪睡陪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機與錄音兰迫,去河邊找鬼信殊。 笑死,一個胖子當著我的面吹牛汁果,可吹牛的內(nèi)容都是我干的涡拘。 我是一名探鬼主播,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼据德,長吁一口氣:“原來是場噩夢啊……” “哼鳄乏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起棘利,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤橱野,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后善玫,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體水援,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年茅郎,在試婚紗的時候發(fā)現(xiàn)自己被綠了蜗元。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,953評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡只洒,死狀恐怖许帐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情毕谴,我是刑警寧澤成畦,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站涝开,受9級特大地震影響循帐,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舀武,卻給世界環(huán)境...
    茶點故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一拄养、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧银舱,春花似錦瘪匿、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至诚欠,卻和暖如春顽染,著一層夾襖步出監(jiān)牢的瞬間漾岳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工粉寞, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留尼荆,地道東北人。 一個月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓唧垦,卻偏偏與公主長得像捅儒,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子振亮,可洞房花燭夜當晚...
    茶點故事閱讀 44,901評論 2 355