Java保真組合圖片以及生成縮略圖

業務需求:在推送商品給買家的時候,可能會推送多個商品,每一個商品對應一張圖片,如今只須要發送一條消息,那麼就須要將多張圖片組合成一張自定義大小的圖片。java

一、舉例

尺寸:648*300尺寸:1080*454尺寸:600*300尺寸:800*500程序員

若是傳進來了兩張圖片,那麼合成自定義大小的二宮格圖片,若是傳進來四張圖片,合成自定義大小的四宮格圖片(九宮格等等的能夠再本身增長一下web

二、嘗試先等比縮小或放大圖片,而後組合(測試後發現好像不太行)

  • 一、先嚐試生成圖片自定義大小的縮略圖
/**
     * 生成縮略圖
     * 
     * @param imgsrc 圖片路徑
     * @param imgdist 輸出路徑
     * @param widthdist 縮放後圖片長
     * @param heightdist 縮放後圖片寬
     */

    public static void reduceImg(String imgsrc, String imgdist, int widthdist, int heightdist) {
        try {
            File srcfile = new File(imgsrc);
            if (!srcfile.exists()) {
                return;
            }
            Image src = javax.imageio.ImageIO.read(srcfile);
            BufferedImage tag= new BufferedImage(widthdist, heightdist, BufferedImage.TYPE_INT_RGB);
            tag.getGraphics().drawImage(src.getScaledInstance(widthdist, heightdist,  Image.SCALE_SMOOTH), 00,  null);

            FileOutputStream out = new FileOutputStream(imgdist);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            encoder.encode(tag);
            out.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }
public static void main(String[] args) {
        try {
            ImageUtils.reduceImg("/Users/weiwanxi/Downloads/寫做圖片/aqs.jpeg""/Users/weiwanxi/Downloads/寫做圖片/treasureMap.jpg"324150);
        } catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }

測試以後生成的圖片:微信

這一步縮略圖實際上是能夠的,按照固定大小縮放也沒有失真,至於我說的不行,是下面這一步。編輯器

  • 二、先嚐試生成四張圖片的縮略圖,而後組合成四宮格
public class ImageUtils2 {

    /**
     * 合成圖片
     *
     * @param imageList 圖片路徑集合
     * @param width 合成圖片的長
     * @param height 合成圖片的寬
     * @throws Exception
     */

    public static void syntheticImage(List<String> imageList, int width, int height) throws Exception {
        // 若是隻有一張圖片,直接返回
        if (imageList.size() == 1){
            return;
        }
        // 構造一個類型爲預約義圖像類型之一的BufferedImage,寬高爲傳進來的參數
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 建立輸出流
        FileOutputStream out = new FileOutputStream("/Users/weiwanxi/Downloads/寫做圖片/treasureMap.jpg");
        // 製圖的寬(長是同樣的)
        int syntheticHeight = 0;
        // 圖片縮放的大小
        int zoomWeight, zoomHeight = 0;
        // 二宮格
        if (imageList.size() == 2){
            zoomWeight = width / 2;
            zoomHeight = height / 2;
            syntheticHeight = height;
        } // 四宮格
        else if (imageList.size() <= 4){
            zoomWeight = width / 4;
            zoomHeight = height / 4;
            syntheticHeight = height/ 2;
        }else {
            throw new RuntimeException();
        }
        BufferedImage img = null;
        for (int i = 0; i < imageList.size(); i++){
            // 繪製合成圖像
            Graphics g = bufferedImage.createGraphics();
            try {
                File file = new File(imageList.get(i));
                img = reduceImg(file, zoomWeight, zoomHeight);
                assert img != null;
                switch (i){
                    case 0:
                        g.drawImage(img, 00, width/2, syntheticHeight, null);
                        break;
                    case 1:
                        g.drawImage(img, width/20, width/2, syntheticHeight, null);
                        break;
                    case 2:
                        g.drawImage(img, 0, height/2, width/2, height/2null);
                        break;
                    case 3:
                        g.drawImage(img, width/2, height/2, width/2, height/2null);
                    default:
                        break;
                }
            }catch (Exception e){
                throw new RuntimeException("繪圖出現異常");
            }finally {
                // 釋放此圖形的上下文以及它使用的全部系統資源。
                g.dispose();
            }
        }
        //將繪製的圖像生成至輸出流
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(bufferedImage);
        //關閉輸出流
        out.close();
        System.out.println("合成圖片完成咯。。");
    }

    /**
     * 生成縮略圖
     *
     * @param image
     * @param width
     * @param height
     * @return
     */

    public static BufferedImage reduceImg(File image, int width, int height) {
        BufferedImage tag = null;
        try {
            Image src = ImageIO.read(image);
            tag= new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            // 繪製圖片
            tag.getGraphics().drawImage(src.getScaledInstance(width, height, Image.SCALE_SMOOTH), 00,  null);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return tag;
    }
}

測試:工具

public static void main(String[] args) {
        try {
            List<String> list = new ArrayList<>();
            list.add("/Users/weiwanxi/Downloads/寫做圖片/aqs.jpeg");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/說着說着.jpg");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/線程池.png");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/樂觀鎖與悲觀鎖.jpg");
            ImageUtils2.syntheticImage(list, 648300);
        } catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }

合成後圖片:648*300學習

能夠看到,這樣合成的圖片失真是比較嚴重的,字都模糊不清,而後我就嘗試了下面這種辦法。測試

三、切割合成圖片的大小,不在比例縮放,由image自動填充

public class ImageUtils {

    /**
     * 合成圖片
     *
     * @param imageList 圖片路徑集合
     * @param width 合成圖片的長
     * @param height 合成圖片的寬
     * @throws Exception
     */

    public static void syntheticImage(List<String> imageList, int width, int height) throws Exception {
        // 若是隻有一張圖片,直接返回
        if (imageList.size() == 1){
            return;
        }
        // 構造一個類型爲預約義圖像類型之一的BufferedImage,寬高爲傳進來的參數
        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 建立輸出流
        FileOutputStream out = new FileOutputStream("/Users/weiwanxi/Downloads/寫做圖片/treasureMap2.jpg");
        // 製圖的寬(長是同樣的)
        int syntheticHeight = 0;
        // 二宮格
        if (imageList.size() == 2){
            syntheticHeight = height;
        } // 四宮格
        else if (imageList.size() <= 4){
            syntheticHeight = height/ 2;
        }else {
            throw new RuntimeException();
        }
        BufferedImage img = null;
        for (int i = 0; i < imageList.size(); i++){
            // 繪製合成圖像
            Graphics g = bufferedImage.createGraphics();
            try {
                File file = new File(imageList.get(i));
                img = javax.imageio.ImageIO.read(file);
                assert img != null;
                switch (i){
                    case 0:
                        g.drawImage(img, 00, width/2, syntheticHeight, null);
                        break;
                    case 1:
                        g.drawImage(img, width/20, width/2, syntheticHeight, null);
                        break;
                    case 2:
                        g.drawImage(img, 0, height/2, width/2, height/2null);
                        break;
                    case 3:
                        g.drawImage(img, width/2, height/2, width/2, height/2null);
                    default:
                        break;
                }
            }catch (Exception e){
                throw new RuntimeException("繪圖出現異常");
            }finally {
                // 釋放此圖形的上下文以及它使用的全部系統資源。
                g.dispose();
            }
        }
        //將繪製的圖像生成至輸出流
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
        encoder.encode(bufferedImage);
        //關閉輸出流
        out.close();
        System.out.println("合成圖片完成咯。。");
    }
  }

測試(二宮格):flex

public static void main(String[] args) {
        try {
            List<String> list = new ArrayList<>();
            list.add("/Users/weiwanxi/Downloads/寫做圖片/aqs.jpeg");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/說着說着.jpg");
//            list.add("/Users/weiwanxi/Downloads/寫做圖片/線程池.png");
//            list.add("/Users/weiwanxi/Downloads/寫做圖片/樂觀鎖與悲觀鎖.jpg");
            ImageUtils.syntheticImage(list, 648300);
        } catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }

合成後圖片:648*300url

測試(四宮格):

public static void main(String[] args) {
        try {
            List<String> list = new ArrayList<>();
            list.add("/Users/weiwanxi/Downloads/寫做圖片/aqs.jpeg");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/說着說着.jpg");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/線程池.png");
            list.add("/Users/weiwanxi/Downloads/寫做圖片/樂觀鎖與悲觀鎖.jpg");
            ImageUtils.syntheticImage(list, 648300);
        } catch (Exception e) {
            System.out.print(e.getMessage());
        }
    }

合成後圖片:648*300

這張圖片看起來失真狀況就比上面那張好不少了,文中示例只寫到了四宮格,若是須要九宮格的話,能夠再補充一下,增長一個九宮格的圖片切割長寬便可!

四、公衆號

若是你以爲個人文章對你有幫助話,歡迎關注個人微信公衆號:"一個快樂又痛苦的程序員"(無廣告,單純分享原創文章、已pj的實用工具、各類Java學習資源,期待與你共同進步)


本文分享自微信公衆號 - 一個快樂又痛苦的程序員(AsuraTechnology)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索