美文网首页
【原创】ImageUtil 和 ImageMerge工具类

【原创】ImageUtil 和 ImageMerge工具类

作者: circle1992 | 来源:发表于2019-07-08 11:00 被阅读0次
    
    import com.drew.imaging.ImageMetadataReader;
    
    import com.drew.imaging.ImageProcessingException;
    
    import com.drew.metadata.Directory;
    
    import com.drew.metadata.Metadata;
    
    import com.drew.metadata.Tag;
    
    import java.awt.*;
    
    import java.awt.image.BufferedImage;
    
    import java.io.IOException;
    
    import java.io.InputStream;
    
    import java.math.BigDecimal;
    
    import java.util.HashMap;
    
    import java.util.Map;
    
    public class ImageUtil {
    
    /**
    
    * 按指定宽度 等比例缩放图片
    
    *
    
        * @param bufferedImage 图片
    
        * @throws IOException
    
    */
    
        public static BufferedImagethumbnail(BufferedImage bufferedImage, String suffix)throws IOException {
    
            Integer originalWidth = bufferedImage.getWidth();
    
            Integer originalHeight = bufferedImage.getHeight();
    
            int wscale = Math.round((originalWidth /500) *100) /100;
    
            int hscale = Math.round((originalHeight /500) *100) /100;
    
            int scale = Math.max(wscale, hscale);
    
            if (scale <2) {
                scale =2;
            }
            int newWidth = originalWidth / scale;
            int newHeight = originalHeight / scale;
            if (suffix !=null &&(suffix.trim().toLowerCase().endsWith("png")         
                  ||suffix.trim().toLowerCase().endsWith("gif"))) {
                  bufferedImage =dealPngAndGif(bufferedImage, newWidth, newHeight);
            }else {
                  bufferedImage =dealCommon(bufferedImage, newWidth, newHeight);
            }
    
            if (newWidth > newHeight) {
                 //长方形宽大于高,截掉部分宽
                int i =new BigDecimal(newWidth).subtract(new BigDecimal(newHeight)).intValue();
                bufferedImage = bufferedImage.getSubimage(i /2, 0, newHeight, newHeight);
            }else if (newWidth < newHeight) {
                //长方形高大于宽,截掉部分高
                int i =new BigDecimal(newHeight).subtract(new BigDecimal(newWidth)).intValue();
                bufferedImage = bufferedImage.getSubimage(0, i /2, newWidth, newWidth);
            }
            return bufferedImage;
    
        }
    
        /**
         * 生成高质量图片
         *
         * @param bufferedImage 图片
         * @throws IOException
         */
        public static BufferedImagehighDefinition(BufferedImage bufferedImage, String suffix)
                                                  throws IOException {
            Integer originalWidth = bufferedImage.getWidth();
            Integer originalHeight = bufferedImage.getHeight();
            if (originalWidth <3000) {
                return bufferedImage;
            }
            int newWidth =new BigDecimal(originalWidth).divide(
                new BigDecimal(1.6), 2, BigDecimal.ROUND_HALF_DOWN).intValue();
            int newHeight =new BigDecimal(originalHeight).divide(
                new BigDecimal(1.6), 2, BigDecimal.ROUND_HALF_DOWN).intValue();
            if (suffix !=null &&(suffix.trim().toLowerCase().endsWith("png") || suffix.trim().toLowerCase().endsWith("gif"))) {
                return dealPngAndGif(bufferedImage, newWidth, newHeight);
            }else {
                return dealCommon(bufferedImage, newWidth, newHeight);
            }
    }
    
        /**
         * 处理gif图片
         *
         * @param bufferedImage 图片流
         * @param width        宽度
         * @param height        高度
         * @return
         */
        private static BufferedImagedealPngAndGif(BufferedImage bufferedImage, int width, int height) {
            // 处理 png 背景变黑的问题
            BufferedImage newImage =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = newImage.createGraphics();
            newImage =graphics2D.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
            graphics2D.dispose();
            graphics2D = newImage.createGraphics();
            graphics2D.drawImage(bufferedImage.getScaledInstance(width, height, Image.SCALE_AREA_AVERAGING), 0, 0, null);
            graphics2D.dispose();
            return newImage;
        }
    
        /**
         * 普通图片处理
         *
         * @param bufferedImage 图片流
         * @param width        宽度
         * @param height        高度
         * @return
         */
        private static BufferedImagedealCommon(BufferedImage bufferedImage, int width, int height) {
             BufferedImage newImage =new BufferedImage(width, height, bufferedImage.getType());
             Graphics graphics = newImage.getGraphics();
             graphics.drawImage(bufferedImage, 0, 0, width, height, null);
             graphics.dispose();
             return newImage;
        }
    
        /**
         * 翻转类
         *
         * @param src
         * @param imagePro
         * @param ro
         * @return
         */
        public static BufferedImageconvert(BufferedImage src, Map imagePro, int ro) {
            int angle =90 * ro;
            int type = src.getColorModel().getTransparency();
            int wid = imagePro.get("width");
            int hei = imagePro.get("height");
            if (ro %2 !=0) {
                int temp = imagePro.get("width");
                imagePro.put("width", imagePro.get("height"));
                imagePro.put("height", temp);
            }
            Rectangle re =new Rectangle(new Dimension(imagePro.get("width"), imagePro.get("height")));
            BufferedImage BfImg =null;
            BfImg =new BufferedImage(re.width, re.height, type);
            Graphics2D g2 = BfImg.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                  RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2.rotate(Math.toRadians(angle), re.width /2, re.height /2);
            g2.drawImage(src, (re.width - wid) /2, (re.height - hei) /2, null);
            g2.dispose();
            return BfImg;
        }
    
        /**
         * 是否需要翻转
         *
         * @param map
         * @return
         */
        public static int getAngle(Map map) {
            int ro =0;
            if (map.get("Orientation") !=null) {
                String ori = map.get("Orientation").toString();
                if (ori.indexOf("90") >=0) {
                    ro =1;
                }else if (ori.indexOf("180") >=0) {
                    ro =2;
                }else if (ori.indexOf("270") >=0) {
                   ro =3;
                }
            }
            return ro;
      }
    
      /**
       * 获取图片exif信息
       *
       * @param inputStream
       * @return
       * @throws ImageProcessingException
       * @throws IOException
       */
        public static MapgetExif(InputStream inputStream)throws ImageProcessingException, IOException {
            Metadata metadata = ImageMetadataReader.readMetadata(inputStream);
            return printExif(metadata);
        }
    
        /**
         * 将旋转角度信息拿到
         */
        private static MapprintExif(Metadata metadata) {
            Map map =new HashMap();
            String tagName =null;
            String desc =null;
            for (Directory directory : metadata.getDirectories()) {
                for (Tag tag : directory.getTags()) {
                    tagName = tag.getTagName();
                    desc = tag.getDescription();
                    if (tagName.equals("Orientation")) {
                          map.put("Orientation", desc);
                    }
                }
             }
            return map;
        }
    
    }
    
    

    -------------------------------------------------------分割线--------------------------------------------------

    
    import javax.imageio.ImageIO;
    
    import java.awt.*;
    
    import java.awt.image.BufferedImage;
    
    import java.io.*;
    
    import java.math.BigDecimal;
    
    /**
     * 图片拼接类.
     */
    public class ImageMerge {
    
      /**
       * 图片拼接类
       *
       * @param inputStreams 图片流
       * @param text1        底部文字1
       * @param text2        底部文字2
       * @param isCodeImage  是否有2维码
       * @return
       * @throws Exception
       */
        public static BufferedImagedoMerge(InputStream[] inputStreams, String text1, String text2, Boolean isCodeImage)throws Exception {
        if (isCodeImage) {
                BufferedImage[] bufferedImages =new BufferedImage[inputStreams.length];
                int width =1600;
                for (int i =0; i < inputStreams.length -1; i++) {
                    bufferedImages[i] = ImageIO.read(inputStreams[i]);
                }
                bufferedImages[inputStreams.length -1] =generateImg(inputStreams[inputStreams.length -1], width, text1, text2);
                return dealImage(bufferedImages, width);
            }else {
                BufferedImage[] bufferedImages =new BufferedImage[inputStreams.length +1];
                int width =1600;
                for (int i =0; i < inputStreams.length; i++) {
                    bufferedImages[i] = ImageIO.read(inputStreams[i]);
                }
    
                if (text1 !=null || text2 !=null) {
                      bufferedImages[inputStreams.length] =generateImg(null, width, text1, text2);
                }
                return dealImage(bufferedImages, width);
            }
        }
    
        /**
         * 图片等宽处理
         *
         * @param bufferedImages 图片缓存
         * @param width          宽度
         * @return
         */
        private static BufferedImagedealImage(BufferedImage[] bufferedImages, int width) {
            BufferedImage[] bufferedImagesNew =new BufferedImage[bufferedImages.length];
            for (int i =0; i < bufferedImages.length; i++) {
                BufferedImage originImage = bufferedImages[i];
                int originWidth = originImage.getWidth();
                int originHeight = originImage.getHeight();
                BigDecimal scale =new BigDecimal(originWidth).divide(new BigDecimal(width), 10, BigDecimal.ROUND_HALF_DOWN);
                int height =new BigDecimal(originHeight).divide(scale, 10, BigDecimal.ROUND_HALF_DOWN).intValue();
                BufferedImage newImage =new BufferedImage(width, height, originImage.getType());
                Graphics graphics = newImage.getGraphics();
                graphics.drawImage(originImage, 0, 0, width, height, null);
                graphics.dispose();
                bufferedImagesNew[i] = newImage;
            }
            return mergeImage(bufferedImagesNew, width);
        }
    
        /**
         * 拼接图片
         *
         * @param images img1 ,img2
         */
        public static BufferedImagemergeImage(BufferedImage[] images, int width) {
            int len = images.length;
            if (len <1) {
                throw new RuntimeException("图片数量小于1");
            }
            int height =0;
            for (int i =0; i < len; i++) {
                height += images[i].getHeight();
            }
            int gap =3;
            height += (len -1) * gap;
            // 生成新图片
            BufferedImage imageNew =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            //增加少许图片间隙
            BufferedImage blank =new BufferedImage(width, gap, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = blank.createGraphics();
            graphics2D.setBackground(Color.WHITE);
            graphics2D.fillRect(0, 0, width, gap);
            int[] blankArray = blank.getRGB(0, 0, width, gap, new int[width * gap], 0, width);
            int startY =0;
            for (int i =0; i < images.length; i++) {
                int iWidth = images[i].getWidth();
                int iHeight = images[i].getHeight();
                // 逐行扫描图像中各个像素的RGB到数组中
                int[] imageArray = images[i].getRGB(0, 0, iWidth, iHeight, new int[iWidth * iHeight], 0, iWidth);
                imageNew.setRGB(0, startY, width, iHeight, imageArray, 0, width);
                startY += iHeight;
                if (i < (images.length -1)) {
                    imageNew.setRGB(0, startY, width, gap, blankArray, 0, width);
                    startY += gap;
                }
            }
            return imageNew;
        }
    
        /**
         * 生成拼接的二维码
         *
         * @param codeInputStream 二维码图片
         * @param width          宽度
         * @param text1          底部文字1
         * @param text2          底部文字2
         * @return
         * @throws Exception
         */
        public static BufferedImagegenerateImg(InputStream codeInputStream, int width, String text1, String text2)throws Exception {
          int height =new BigDecimal(width).divide(new BigDecimal(4), 10,BigDecimal.ROUND_HALF_DOWN).intValue();
            // 生成底部图片
            BufferedImage imageLocal =new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 以原图片为模板
            Graphics2D graphics2D = imageLocal.createGraphics();
            graphics2D.setBackground(Color.WHITE);
            graphics2D.fillRect(0, 0, width, height);
            if (codeInputStream !=null) {
                // 加载用户的二维码
                BufferedImage imageCode = ImageIO.read(codeInputStream);
                // 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
                graphics2D.drawImage(imageCode, width - height + (height /4), height /4, height /2, height /2, null);
            }
            //设置文本样式
            int fontSize =new BigDecimal(width).divide(new BigDecimal(30), 10, BigDecimal.ROUND_HALF_DOWN).intValue();
            graphics2D.setFont(new Font("宋体", Font.BOLD, fontSize));
            graphics2D.setColor(Color.black);
            //计算文字长度,计算居中的x点坐标
            graphics2D.drawString(text1, width /20, (height /4) + fontSize);
            graphics2D.setFont(new Font("宋体", Font.PLAIN, fontSize *7 /10));
            graphics2D.setColor(Color.darkGray);
            graphics2D.drawString(text2, width /20, (height *3 /4) - (fontSize /2));
            return imageLocal;
         }
    }
    
    

    使用方式:

             int ro = ImageUtil.getAngle(ImageUtil.getExif(file.getInputStream())); --判断图片是否旋转
    
             BufferedImage afterImage = ImageUtil.convert(bufferedImage, imagePro, ro); --判断图片是否旋转
    
             afterImage = ImageUtil.highDefinition(afterImage, extName); -- 生成高质量图片
    
             BufferedImage thumbnail = ImageUtil.thumbnail(afterImage, extName); --生成缩略图
    
             ImageMerge.doMerge(inputStreams, text1, text2, isCodeImage);  --图片拼接
    

    相关文章

      网友评论

          本文标题:【原创】ImageUtil 和 ImageMerge工具类

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