美文网首页图片视频处理
【JAVA】 后端 图片裁剪、压缩 及 视频压缩

【JAVA】 后端 图片裁剪、压缩 及 视频压缩

作者: 扮鬼之梦 | 来源:发表于2020-11-02 11:32 被阅读0次

    本人使用java封装的后端媒体处理工具包

    基于ImageMagick和FFmpeg客户端,使用java调用命令行实现
    https://gitee.com/gnliscream/multimedia-utils

    介绍

    java后端的图片、视频处理工具jar包

    1.获取视频信息

    2.生成视频封面图

    3.异步压缩视频(生成输出文件名后,调用异步压缩视频方法,且同一时间只会处理一个视频,多个请求的视频会进行排队处理)

    4.异步压缩视频完成时回调通知

    5.图片裁切

    6.图片压缩

    客户端安装

    运行环境需安装FFmpeg和ImageMagick,官网地址如下:

    FFmpeg:https://ffmpeg.org/

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

    FFmpeg解压后需设置/bin目录的环境变量,ImageMagick安装版安装后会自动设置环境变量。

    引入依赖

    <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需要是单例的,FFmpegUtils实例交由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);
    
            // 调用视频处理工具类
            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);
    
            // 调用视频处理工具类
            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);
    
            // 调用视频处理工具类
    
    
            CompressionAttributes compressionAttributes = new CompressionAttributes();
            // 设置视频压缩完成时的回调URL
            compressionAttributes.setProgressUrl("http://localhost:8999/file/callback?fileId=111111&a=456");
    
            // 设置视频压缩参数
            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;
        }
    
        /**
         * 压缩视频完成时的回调
         */
        @PostMapping("/callback")
        public Object callback(@RequestBody String info, @RequestParam("fileId") String fileId, @RequestParam("a") String a) {
            // 回调信息
            String[] split = info.split("/");
    
            // 回调参数 fileId,根据fileId查询数据库的上传临时文件名和下载临时文件名,进行文件上传和文件删除
            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);
    
            // 调用图片处理工具类
            // 裁切成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);
    
            // 调用图片处理工具类
            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转化为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转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)

    参数介绍

    输入参数
    参数 类型 必需 注释
    tempDirectory String 临时文件目录
    inputFileName String 输入文件名
    cropAttributes CropAttributes 裁切参数
    resizeAttributes ResizeAttributes 修改分辨率参数
    outputFileSuffix Suffix 输出文件格式,未设置则同输入文件格式

    其中:

    CropAttributes

    参数 类型 必需 注释
    width Integer 裁切图片的宽
    height Integer 裁切图片的高
    leftOffset Integer 距左边偏移量
    topOffset Integer 距顶部偏移量

    ResizeAttributes

    参数 类型 必需 注释
    width Integer 输出图片的宽,只填写宽则高自适应
    height Integer 输出图片的高,只填写高则宽自适应
    quality Integer 输出图片的质量,范围0~100,默认100
    输出参数
    参数 类型 必需 注释
    outputFileName String 输出文件名

    视频工具FFmpegUtils

    方法

    1.获取视频信息

    getInfo(tempDirectory,inputFileName)

    输入参数
    参数 类型 必需 注释
    tempDirectory String 临时文件目录
    inputFileName String 输入文件名
    输出参数
    参数 类型 必需 注释
    format FFFormat 文件信息
    videoInfo VideoInfo 视频信息
    audioInfo AudioInfo 音频信息

    其中:

    FFFormat

    参数 类型 必需 注释
    filename String 文件名全路径名
    duration String 文件时长
    size String 文件大小
    bitRate String 文件比特率

    VideoInfo

    参数 类型 必需 注释
    codecName String 视频 编码名称
    codecType String 类型 video
    width Integer 视频 宽度
    height Integer 视频 高度
    frameRate Integer 视频 帧率
    duration Integer 视频 时长
    bitRate Integer 视频 比特率
    nbFrames Integer 视频 总帧数

    AudioInfo

    参数 类型 必需 注释
    codecName String 音频 编码名称
    codecType String 类型 audio
    duration Integer 音频 时长
    bitRate Integer 音频 比特率
    sampleRate Integer 音频 采样率
    channels Integer 音频 声道数 1:单声道 2:双声道
    2.截取视频封面

    createCover(tempDirectory, inputFileName, outputFileSuffix)

    createCover(tempDirectory, inputFileName)

    输入参数
    参数 类型 必需 注释
    tempDirectory String 临时文件目录
    inputFileName String 输入文件名
    outputFileSuffix Suffix 输出文件格式,默认jpg
    输出参数
    参数 类型 必需 注释
    outputFileName String 输出文件名
    3.视频压缩

    putCompressionTask(tempDirectory, inputFileName, compressionAttributes)

    putCompressionTask(tempDirectory, inputFileName, compressionAttributes, outputFileName)

    输入参数
    参数 类型 必需 注释
    tempDirectory String 临时文件目录
    inputFileName String 输入文件名
    compressionAttributes CompressionAttributes 压缩参数
    outputFileName String 输出文件名,默认UUID生成

    其中:

    CompressionAttributes

    参数 类型 必需 注释
    videoAttributes VideoAttributes 视频压缩参数
    audioAttributes AudioAttributes 音频压缩参数
    progressUrl String 压缩完成后的回调地址

    VideoAttributes

    参数 类型 必需 注释
    codec VideoCodec 视频编码(默认libx264,libx265)
    maxFps Integer 最大帧率
    videoSize VideoSize 视频分辨率(hd480,hd720,hd1080,800x800)
    maxDuration Integer 最大时长
    maxBitRate Integer 视频最大比特率

    AudioAttributes

    参数 类型 必需 注释
    maxBitRate Integer 音频最大比特率
    maxSamplingRate Integer 音频最大采样率
    输出参数
    参数 类型 必需 注释
    outputFileName String 输出文件名

    ImageMagick官网

    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官网

    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 设置声道数为1
    -ar 48000 设置采样率为48000Hz

    截取视频生成图片

    从第-ss秒开始,每秒截取-r张图片,持续-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

    网上的开源框架

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

    网上的相关资料

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

    相关文章

      网友评论

        本文标题:【JAVA】 后端 图片裁剪、压缩 及 视频压缩

        本文链接:https://www.haomeiwen.com/subject/vwzpvktx.html