如何将文档、视频某页或某帧转换成图片?

11 篇文章 0 订阅

目录

一、需求背景

二、引入依赖

三、根据自身的业务编写合适的代码


一、需求背景

        博主的大概需求是,获取第一章第一节的课件(有pdf、各种文档、视频等形式),生成课程的封面图片。

二、引入依赖
 

        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacv</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco</groupId>
            <artifactId>javacpp</artifactId>
            <version>1.4.1</version>
        </dependency>
        <dependency>
            <groupId>org.bytedeco.javacpp-presets</groupId>
            <artifactId>ffmpeg-platform</artifactId>
            <version>3.4.2-1.4.1</version>
        </dependency>

三、根据自身的业务编写合适的代码

/**
     * 保存课程信息自动设置课程封面图片
     * @param courseInformation
     * @param coursewareId
     */
    private void setDefaultCourseCoverPhoto(CourseInformation courseInformation, Long coursewareId) {
        String key = "";
        InputStream pdfStream = null;
        PDDocument pdfDocument = null;
        try {
            CoursewareLibrary library = coursewareLibraryMapper.selectById(coursewareId);
            //获取网络流
            String urlByPreviewPdf = documentManagementApiServer.getUrlByPreviewPdf(library.getSourceFileKey());
            pdfStream = ImageUtil.getImageStream(urlByPreviewPdf);
            if (BusinessConstant.COURSEWARE_LIBRARY_VIDEO.equals(library.getCoursewareType()) ||
                    BusinessConstant.COURSEWARE_LIBRARY_AUDIO.equals(library.getCoursewareType())){
                pdfStream = returnBitMap(urlByPreviewPdf);
                //1.生成本地源文件、目的文件
                String source = tempPath + "/source/" + library.getSourceFileKey();
                MultipartFile multipartFile = FileUtil.getMultipartFile(pdfStream, library.getSourceFileKey());
                File file = FileUtil.toFile(multipartFile);
                BufferedImage buffImage = VideoCaptureUtils.generatePhoto(source,file.getPath());
                MultipartFile uploadMultipartFile = fileCase(buffImage);
                key = uploadPhoto(uploadMultipartFile);
                FileUtil.del(file);
                FileUtil.del(source);
            }else if (BusinessConstant.COURSEWARE_LIBRARY_FILE.equals(library.getCoursewareType()) ||
                    BusinessConstant.COURSEWARE_LIBRARY_PDF.equals(library.getCoursewareType())){
                pdfDocument = PDDocument.load(pdfStream);
                //PDFRenderer的类将PDF文档呈现为AWT BufferedImage
                PDFRenderer pdfRenderer = new PDFRenderer(pdfDocument);
                // 提取的页码
                int pageNumber = 0;
                // 以300 dpi 读取存入 BufferedImage 对象
                int dpi = 500;
                //Renderer类的renderImage()方法在特定页面中渲染图像
                BufferedImage buffImage = pdfRenderer.renderImageWithDPI(pageNumber, dpi, ImageType.RGB);
                // 文件类型转换
                MultipartFile multipartFile = fileCase(buffImage);
                key = uploadPhoto(multipartFile);
                // 关闭文档
                pdfDocument.close();
                //删除临时文件
//                        log.info("临时文件的目录:"+s);
            }
            courseInformation.setCoverPhotoKey(key);
        }catch (Exception e){
            log.error("{}",e);
            e.printStackTrace();
        }finally {
            IOUtils.closeQuietly(pdfStream);
            IOUtils.closeQuietly(pdfDocument);
        }
    }
    public static MultipartFile getMultipartFile(InputStream inputStream, String fileName) {
        FileItem fileItem = createFileItem(inputStream, fileName);
        return new CommonsMultipartFile(fileItem);
    }


    public static File toFile(MultipartFile multipartFile) {
        String fileName = multipartFile.getOriginalFilename();
        String prefix = "." + getExtensionName(fileName);
        File file = null;

        try {
            file = File.createTempFile(IdUtil.simpleUUID(), prefix);
            multipartFile.transferTo(file);
        } catch (IOException var5) {
            var5.printStackTrace();
        }

        return file;
    }


    /**
     * 将buffImage转换为MultipartFile
     * @param buffImage
     * @return MultipartFile
     */
    private MultipartFile fileCase(BufferedImage buffImage) {
        //得到BufferedImage对象
        // BufferedImage bufferedImage = JoinTwoImage.testEncode(200, 200, url);
        MultipartFile multipartFile= null;
        try {
            //创建一个ByteArrayOutputStream
            ByteArrayOutputStream os = new ByteArrayOutputStream();
            //把BufferedImage写入ByteArrayOutputStream
            ImageIO.write(buffImage, "jpg", os);
            //ByteArrayOutputStream转成InputStream
            InputStream input = new ByteArrayInputStream(os.toByteArray());
            //InputStream转成MultipartFile
            multipartFile =new MockMultipartFile("file", "file.jpg", "text/plain", input);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return multipartFile;
    }
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class VideoCaptureUtils {

    /**
     *
     * @Title: getTempPath
     * @Description: 生成视频的首帧图片方法
     * @author: Zing
     * @param: @param tempPath 生成首帧图片的文件地址
     * @param: @param filePath 传进来的线上文件
     * @param: @return
     * @param: @throws Exception
     * @return: boolean
     * @throws
     */
    public static BufferedImage generatePhoto(String tempPath, String filePath) throws Exception {
        File targetFile = new File(tempPath);
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        File file2 = new File(filePath);
        BufferedImage bufferedImage = null;
        //判断文件是否为视频
        if(isVideo(filePath)) {
            if (file2.getParentFile().exists()) {
                FFmpegFrameGrabber ff = new FFmpegFrameGrabber(file2);
                ff.start();
                int ftp = ff.getLengthInFrames();
                int flag=0;
                Frame frame = null;
                while (flag <= ftp) {
                    //获取帧
                    frame = ff.grabImage();
                    //过滤前3帧,避免出现全黑图片
                    if ((flag>3)&&(frame != null)) {
                        break;
                    }
                    flag++;
                }
//                if(ImageIO.write(FrameToBufferedImage(frame), "jpg", targetFile)) {
//                    ff.close();
//                    ff.stop();
//                    return true;
//                }else {
//                    ff.close();
//                    ff.stop();
//                    return false;
//                }
                bufferedImage = FrameToBufferedImage(frame);
                ImageIO.write(bufferedImage, "jpg", targetFile);
                ff.close();
                ff.stop();
            }
        }
        return bufferedImage;
    }

    /***
     *
     * @Title: FrameToBufferedImage
     * @Description: 创建格式化BufferedImage对象
     * @author: Zing
     * @param: @param frame
     * @param: @return
     * @return: RenderedImage
     * @throws
     */
    private static BufferedImage FrameToBufferedImage(Frame frame) {
        //创建BufferedImage对象
        Java2DFrameConverter converter = new Java2DFrameConverter();
        BufferedImage bufferedImage = converter.getBufferedImage(frame);
        return bufferedImage;
    }

    /**
     *
     * @Title: isVideo
     * @Description:判断是不是视频
     * @author: Zing
     * @param: @param path 文件路径
     * @param: @return
     * @return: boolean       true是视频 false非视频
     * @throws
     */
    public static boolean isVideo(String path) {
        List<String> typeList = new ArrayList<String>();
        typeList.add("mp4");
        typeList.add("flv");
        typeList.add("avi");
        typeList.add("rmvb");
        typeList.add("rm");
        typeList.add("wmv");
        //获取文件名和后缀
        String suffix = path.substring(path.lastIndexOf(".") + 1);
        for(String type : typeList) {
            if(type.equalsIgnoreCase(suffix)) {
                return true;
            }
        }
        return false;
    }

    public static BufferedImage resize(BufferedImage img, int newW, int newH) {
        int w = img.getWidth();
        int h = img.getHeight();
        BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
        Graphics2D g = dimg.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
        g.dispose();
        return dimg;
    }
}

各位可以关注下面这个公众号,这个公众号会分享一些相关的技术型的文章或者开发遇到的常见问题。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值