JAVA-仿微信九宮格頭像

最近有個需求楼誓,需要App實現(xiàn)群頭像仿微信九宮格排列,由于讓客戶端生成頭像顯示會比較慢火惊,因此只能用服務(wù)端實現(xiàn)這個需求,但是網(wǎng)上找都不是很符合要求春锋,于是自己動手改了下實現(xiàn)了該功能:

public final class ImageUtil {

    /**
     * 圖片的間隙
     */
    private static final int SIDE = 6;
    /**
     * 畫板尺寸
     */
    private static final int CANVANS_W = 112;
    private static final int CANVANS_H = 112;

    /**
     * 尺寸1 (小)
     */
    private static final int ONE_IMAGE_SIZE = CANVANS_H - (2 * SIDE);
    /**
     * 尺寸2 (中)
     */
    private static final int TWO_IMAGE_SIZE = (CANVANS_H - (3 * SIDE)) / 2;
    /**
     * 尺寸3 (大)
     */
    private static final int FIVE_IMAGE_SIZE = (CANVANS_H - (4 * SIDE)) / 3;

    private ImageUtil() {
    }

    /**
     * 生成群組頭像
     *
     * @param paths   圖片鏈接
     * @param dir     輸出路徑
     * @param groupId 群編號
     * @return
     * @throws IOException
     */
    public static boolean getCombinationOfhead(List<String> paths, String dir, String groupId)
            throws IOException {
        List<BufferedImage> bufferedImages = new ArrayList<BufferedImage>();

        int imageSize = 0;
        if (paths.size() <= 1) {
            //若為一張圖片
            imageSize = ONE_IMAGE_SIZE;
        } else if (paths.size() > 1 && paths.size() < 5) {
            //若為2-4張圖片

            imageSize = TWO_IMAGE_SIZE;
        } else {
            //若>=5張圖片
            imageSize = FIVE_IMAGE_SIZE;
        }

        for (int i = 0; i < paths.size(); i++) {
            BufferedImage resize2 = ImageUtil.resize2(paths.get(i), imageSize, imageSize, true);
            bufferedImages.add(resize2);
        }

        BufferedImage outImage = new BufferedImage(CANVANS_W, CANVANS_H, BufferedImage.TYPE_INT_RGB);

        // 生成畫布
        Graphics g = outImage.getGraphics();

        Graphics2D g2d = (Graphics2D) g;

        // 設(shè)置背景色
        g2d.setBackground(new Color(231, 231, 231));

        // 通過使用當(dāng)前繪圖表面的背景色進行填充來清除指定的矩形狱杰。
        g2d.clearRect(0, 0, CANVANS_W, CANVANS_H);

        // 開始拼湊 根據(jù)圖片的數(shù)量判斷該生成那種樣式的組合頭像目前為九種

        for (int i = 1; i <= bufferedImages.size(); i++) {
            Integer size = bufferedImages.size();
            switch (size) {
                case 1:
                    g2d.drawImage(bufferedImages.get(i - 1), SIDE, SIDE, null);
                    break;
                case 2:
                    if (i == 1) {
                        g2d.drawImage(bufferedImages.get(i - 1), SIDE, (CANVANS_W - imageSize) / 2, null);
                    } else {
                        g2d.drawImage(bufferedImages.get(i - 1), 2 * SIDE + imageSize, (CANVANS_W - imageSize) / 2, null);
                    }
                    break;
                case 3:
                    if (i == 1) {
                        g2d.drawImage(bufferedImages.get(i - 1), (CANVANS_W - imageSize) / 2, SIDE, null);
                    } else {
                        g2d.drawImage(bufferedImages.get(i - 1), (i - 1) * SIDE + (i - 2) * imageSize, imageSize + (2 * SIDE), null);

                    }
                    break;
                case 4:

                    if (i <= 2) {
                        g2d.drawImage(bufferedImages.get(i - 1), i * SIDE + (i - 1) * imageSize, SIDE, null);

                    } else {
                        g2d.drawImage(bufferedImages.get(i - 1), (i - 2) * SIDE + (i - 3) * imageSize, imageSize + 2 * SIDE, null);

                    }
                    break;
                case 5:
                    if (i <= 2) {
                        g2d.drawImage(bufferedImages.get(i - 1), (CANVANS_W - 2 * imageSize - SIDE) / 2 + (i - 1) * imageSize + (i - 1) * SIDE, (CANVANS_W - 2 * imageSize - SIDE) / 2, null);

                    } else {
                        g2d.drawImage(bufferedImages.get(i - 1), (i - 2) * SIDE + (i - 3) * imageSize, ((CANVANS_W - 2 * imageSize - SIDE) / 2) + imageSize + SIDE, null);

                    }
//
                    break;
                case 6:
                    if (i <= 3) {
                        g2d.drawImage(bufferedImages.get(i - 1), SIDE * i + imageSize * (i - 1), (CANVANS_W - 2 * imageSize - SIDE) / 2, null);
                    } else {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 3) * SIDE) + ((i - 4) * imageSize), ((CANVANS_W - 2 * imageSize - SIDE) / 2) + imageSize + SIDE, null);
                    }
                    break;
                case 7:
                    if (i <= 1) {
                        g2d.drawImage(bufferedImages.get(i - 1), 2 * SIDE + imageSize, SIDE, null);
                    }
                    if (i <= 4 && i > 1) {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 1) * SIDE) + ((i - 2) * imageSize), 2 * SIDE + imageSize, null);
                    }
                    if (i <= 7 && i > 4) {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 4) * SIDE) + ((i - 5) * imageSize), 3 * SIDE + 2 * imageSize, null);
                    }
                    break;
                case 8:
                    if (i <= 2) {
                        g2d.drawImage(bufferedImages.get(i - 1), (CANVANS_W - 2 * imageSize - SIDE) / 2 + (i - 1) * imageSize + (i - 1) * SIDE, SIDE, null);
                    }
                    if (i <= 5 && i > 2) {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 2) * SIDE) + ((i - 3) * imageSize), 2 * SIDE + imageSize, null);
                    }
                    if (i <= 8 && i > 5) {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 5) * SIDE) + ((i - 6) * imageSize), 3 * SIDE + 2 * imageSize, null);
                    }
                    break;
                case 9:
                    if (i <= 3) {
                        g2d.drawImage(bufferedImages.get(i - 1), (i * SIDE) + ((i - 1) * imageSize), SIDE, null);
                    }
                    if (i <= 6 && i > 3) {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 3) * SIDE) + ((i - 4) * imageSize), 2 * SIDE + imageSize, null);
                    }
                    if (i <= 9 && i > 6) {
                        g2d.drawImage(bufferedImages.get(i - 1), ((i - 6) * SIDE) + ((i - 7) * imageSize), 3 * SIDE + 2 * imageSize, null);
                    }
                    break;
                default:
                    break;
            }
        }

        StringBuffer outPath = new StringBuffer().append(dir)
                .append(File.separatorChar)
                .append("GP-" + groupId).append(".jpg");

        String format = "JPG";
        File file = new File(outPath.toString());
        if (!file.exists()) {
            file.mkdirs();
        }
        return ImageIO.write(outImage, format, file);
    }

  /**
     * 圖片縮放
     *
     * @param filePath 圖片路徑
     * @param height   高度
     * @param width    寬度
     * @param bb       比例不對時是否需要補白
     */
    public static BufferedImage resize2(String filePath, int height, int width,
                                        boolean bb) {
        try {
            double ratio = 0; // 縮放比例
//            System.out.println("圖片縮放"+filePath);
            BufferedImage bi = null;
            if (filePath.indexOf("http://") == 0) {
                bi = ImageIO.read(new URL(filePath));
            } else {
                bi = ImageIO.read(new File(filePath));
            }
            Image itemp = bi.getScaledInstance(width, height,
                    Image.SCALE_SMOOTH);
            // 計算比例
            if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
                if (bi.getHeight() > bi.getWidth()) {
                    ratio = (new Integer(height)).doubleValue()
                            / bi.getHeight();
                } else {
                    ratio = (new Integer(width)).doubleValue() / bi.getWidth();
                }
                AffineTransformOp op = new AffineTransformOp(
                        AffineTransform.getScaleInstance(ratio, ratio), null);
                itemp = op.filter(bi, null);
            }
            if (bb) {
                BufferedImage image = new BufferedImage(width, height,
                        BufferedImage.TYPE_INT_RGB);
                Graphics2D g = image.createGraphics();
                g.setColor(Color.white);
                g.fillRect(0, 0, width, height);
                if (width == itemp.getWidth(null)) {
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                } else {
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                }
                g.dispose();
                itemp = image;
            }
            return (BufferedImage) itemp;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 刪除文件
     * @param path
     * @param filename
     */
    public void delFile(String path, String filename) {
        File file = new File(path + "/" + filename);

        if (file.exists() && file.isFile()) {
            file.delete();
        }
    }

   /**
     * 可依次生成九種情況的群頭像
     *
     * @param args
     * @throws IOException
     */
    public static void main(String[] args) throws IOException {
        Integer groupId = 0;
        for (int i = 1; i < 10; i++) {
            List<String> list = new ArrayList<>();
            for (int j = 0; j < i; j++) {
                //本地圖片路徑或者網(wǎng)絡(luò)圖片路徑
                list.add("/Users/Basil/Desktop/1.jpg");
            }
            File file = new File("");
            //生成目錄
            String path = file.getCanonicalPath() + "/src/main/webapp/temp/";
            groupId++;
            ImageUtil.getCombinationOfhead(list, path, groupId.toString());
        }
    }

生成的效果圖:

image.png

詳細效果圖:

GP-1.jpg
GP-2.jpg
GP-3.jpg
GP-4.jpg
GP-5.jpg
GP-6.jpg
GP-7.jpg
GP-8.jpg
GP-9.jpg
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末瘦材,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子仿畸,更是在濱河造成了極大的恐慌食棕,老刑警劉巖朗和,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異簿晓,居然都是意外死亡眶拉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進店門憔儿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忆植,“玉大人,你說我怎么就攤上這事谒臼〕” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵蜈缤,是天一觀的道長拾氓。 經(jīng)常有香客問我,道長底哥,這世上最難降的妖魔是什么咙鞍? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任畜号,我火速辦了婚禮苍碟,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘谜悟。我一直安慰自己附较,他們只是感情好吃粒,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拒课,像睡著了一般徐勃。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上早像,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天僻肖,我揣著相機與錄音,去河邊找鬼卢鹦。 笑死臀脏,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的冀自。 我是一名探鬼主播揉稚,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼熬粗!你這毒婦竟也來了搀玖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤驻呐,失蹤者是張志新(化名)和其女友劉穎灌诅,沒想到半個月后芳来,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡猜拾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年即舌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挎袜。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡顽聂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出盯仪,到底是詐尸還是另有隱情芜飘,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布磨总,位于F島的核電站,受9級特大地震影響笼沥,放射性物質(zhì)發(fā)生泄漏蚪燕。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一奔浅、第九天 我趴在偏房一處隱蔽的房頂上張望馆纳。 院中可真熱鬧,春花似錦汹桦、人聲如沸鲁驶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钥弯。三九已至,卻和暖如春督禽,著一層夾襖步出監(jiān)牢的瞬間脆霎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工狈惫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留睛蛛,地道東北人。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓胧谈,卻偏偏與公主長得像忆肾,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子菱肖,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容