zoukankan      html  css  js  c++  java
  • java实现上传自动生成缩略图

    最近做项目需求,前台上传文件等后台自动处理缩略图,在统一文件管理页面展示

    使用了一些工具和方法实现了对图片,文档,视频的缩率图获取,

    首先是依赖如下

            <!-- pdf生成缩率图依赖 -->
            <dependency>
                <groupId>org.apache.pdfbox</groupId>
                <artifactId>pdfbox</artifactId>
                <version>2.0.24</version>
            </dependency>
            <!--   操作视频获取缩略图依赖     -->
            <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacpp</artifactId>
                <version>1.4.3</version>
            </dependency>
            <dependency>
                <groupId>org.bytedeco</groupId>
                <artifactId>javacv</artifactId>
                <version>1.4.3</version>
            </dependency>
            <dependency>
                <groupId>org.bytedeco.javacpp-presets</groupId>
                <artifactId>ffmpeg-platform</artifactId>
                <version>4.0.2-1.4.3</version>
            </dependency>

    视频转换ffmeg也可以使用安装软件的方式调用,大批量转换时效率更高,在本需求中使用的是异步多线程处理的方式
    图片直接使用javax自带的ImageIO操作即可,文档类的转换思路是将doc,docx,xls等文档类型转化为pdf再使用pdfbox获取第一张生成为缩率图

    public class FileToThumbnail {
     /**
         * <p>Title: thumbnailImage</p>
         * <p>Description: 根据图片路径生成缩略图 </p>
         * @param imagePath    原图片路径
         * @param w            缩略图宽
         * @param h            缩略图高
         * @param prevfix    生成缩略图的前缀
         * @param force      是否强制按照宽高生成缩略图(如果为false,则生成最佳比例缩略图)
         */
        public void getThumbnailForPic(String imagePath, int w, int h, String prevfix, boolean force) throws IOException {
            File imgFile = new File(imagePath);
            if(imgFile.exists()){
                    // ImageIO 支持的图片类型 : [BMP, bmp, jpg, JPG, wbmp, jpeg, png, PNG, JPEG, WBMP, GIF, gif]
                    String types = Arrays.toString(ImageIO.getReaderFormatNames());
                    String suffix = null;
                    // 获取图片后缀
                    if(imgFile.getName().indexOf(".") > -1) {
                        suffix = imgFile.getName().substring(imgFile.getName().lastIndexOf(".") + 1);
                    }
                    // 类型和图片后缀全部小写,然后判断后缀是否合法
                    if(suffix == null || types.toLowerCase().indexOf(suffix.toLowerCase()) < 0){
                        System.out.println("Sorry, the image suffix is illegal. the standard image suffix is {}." + types);
                        return ;
                    }
                    System.out.println("target image's size, {"+w+"}, height:{"+h+"}.");
                    Image img = ImageIO.read(imgFile);
                    if(!force){
                        // 根据原图与要求的缩略图比例,找到最合适的缩略图比例
                        int width = img.getWidth(null);
                        int height = img.getHeight(null);
                        if((width*1.0)/w < (height*1.0)/h){
                            if(width > w){
                                h = Integer.parseInt(new java.text.DecimalFormat("0").format(height * w/(width*1.0)));
                            }
                        } else {
                            if(height > h){
                                w = Integer.parseInt(new java.text.DecimalFormat("0").format(width * h/(height*1.0)));
                            }
                        }
                    }
                    BufferedImage bi = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
                    Graphics g = bi.getGraphics();
                    g.drawImage(img, 0, 0, w, h, Color.LIGHT_GRAY, null);
                    g.dispose();
                    String p = imgFile.getPath();
                    // 将图片保存在原目录并加上前缀
                    ImageIO.write(bi, suffix, new File(p.substring(0,p.lastIndexOf(File.separator)) + File.separator + prevfix +imgFile.getName()));
            }
        }
    
    
        /**
         * 通过PDFbox生成文件的缩略图
         *
         * @param filePath:文件路径
         * @param outPath:输出图片路径
         * @throws IOException
         */
        public  String getThumbnailForPdf(String filePath, String outPath) throws IOException {
            // 利用PdfBox生成图像
            PDDocument pdDocument = PDDocument.load(new File(filePath));
            PDFRenderer renderer = new PDFRenderer(pdDocument);
            // 构造图片
            BufferedImage img_temp = renderer.renderImageWithDPI(0, 30, ImageType.RGB);
            ImageIO.write(img_temp,"png",new File(outPath));
            pdDocument.close();
            return outPath;
        }
        /**
         * @description //生成视频缩略图的URL地址
         * @param sourcePath 保存路径
         * @return String 保存路径
         */
        public String getThumbnailForVideo(InputStream inputStream,String sourcePath) throws IOException {
            File targetFile = new File(sourcePath);
    
            FFmpegFrameGrabber ff = new FFmpegFrameGrabber(inputStream);
            ff.start();
            // 视频总帧数
            int videoLength = ff.getLengthInFrames();
            Frame f  = null;
            int i = 0;
            while (i < videoLength) {
                // 过滤前20帧,因为前20帧可能是全黑的
                // 这里看需求,也可以直接根据帧数取图片
                f = ff.grabFrame();
                if (i > 20 && f.image != null) {
                    break;
                }
                i++;
            }
            int owidth = f.imageWidth;
            int oheight = f.imageHeight;
            // 对截取的帧进行等比例缩放
            int width = 300;
            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);
            ImageIO.write(bi, "png", targetFile);
            // 查看stop源码会自动关流
            ff.stop();
            return sourcePath;
    
        }
    
    
    }

    文档转pdf的好用的工具基本付费,如果有win环境推荐jcob,其他的自行百度或使用poi,easypoi等试一下(前面博客有处理过word)
    后续处理思路是建立任务类,根据分类需求进行不同处理,在上传完成后调度异步任务即可,也可以用消息队列,也加一个定期执行定时任务,可以防止文件服务器掉线导致丢失处理(做好错误处理就可以不用)

  • 相关阅读:
    Java 时钟
    mybatis中的#和$的区别
    vuex数据管理-数据共享
    vuex数据管理-数据适配
    vue双向数据绑定原理
    基于VUE的SPA单页应用开发-加载性能篇
    vue2.0读书笔记3
    移动端软键盘收起监听
    移动端模态窗口的滚动和橡皮筋问题解决方案
    window.history的跳转实质-HTML5 history API 解析
  • 原文地址:https://www.cnblogs.com/yanyunpiaomaio/p/14999142.html
Copyright © 2011-2022 走看看