用java实现给你的头像) +n

首先, 其实应该把标题改为——给任意图片右上角套上红色消息数目框;
代码如下:

//主程序:

package cn.sourcecodes.main;

import cn.sourcecodes.utils.DecorationUtil;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Scanner;

/**
 * Created by cn.sourcecodes on 2016/11/26.
 */
public class DecoratePicture {

    public static final String OUTPUT_DIRECTORY = "d://decoratedPictures/";

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);

        //如果输出文件夹不存在, 创建它
        File dir = new File(DecoratePicture.OUTPUT_DIRECTORY);
        if(!dir.exists()) {
            System.out.println("not exist");
            dir.mkdir();
        }

        boolean isQuit = false;
        while(!isQuit) {
            String inputPath;
            String messageNum;

            System.out.println("请输入文件路径如(d://test/test.jpg, 开头盘符后必须接 // 否则生成文件文件名不规范)");
            inputPath = input.nextLine();
            System.out.println("请输入消息数: ");
            messageNum = input.nextLine();

            File file = new File(inputPath);
            try {
                BufferedImage sourceImage = ImageIO.read(file);
                DecorationUtil.getAfterCombine(Integer.valueOf(messageNum), sourceImage);

                String outputPath = DecoratePicture.OUTPUT_DIRECTORY + "decorated_" + getFileName(inputPath);//输出文件路径
                
                OutputStream output = new FileOutputStream(outputPath);

                String format = getFileName(inputPath).split("\\.")[1];  //获取文件格式名, 比如  jpg
                
                ImageIO.write(sourceImage, format, output);

                output.close();

                System.out.println("quit 退出, 任意字符继续");
                String action = input.nextLine();

                if(action.equals("quit")) {
                    isQuit = true;
                }
            } catch (IOException e) {
                System.out.println("文件不存在");
            } catch (NumberFormatException e) {
                System.out.println("输入的不是数字");
            } catch (Exception e) {
                System.out.println("未知异常");
            }
        }
    }

    //获取传入文件的文件名
    public static String getFileName(String path) {
        String temp = path.substring(4); //去掉前面盘符, 如: d://

        //分割获取最后一个,就是文件名
        String[] splitTemp = temp.split("/");
        String fileName = splitTemp[splitTemp.length-1];

        return fileName;
    }
}



//工具类 package cn.sourcecodes.utils;

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;

/**
 * Created by cn.sourcecodes on 2016/11/26.
 */
public class DecorationUtil {

    public static void getAfterCombine(int messageNum, BufferedImage bufferedImage) {
        int pictureWidth = bufferedImage.getWidth();
        int pictureHeight = bufferedImage.getHeight();

        Graphics2D graphics2D = bufferedImage.createGraphics();

        BufferedImage messageImage = getMessageCircle(messageNum, pictureWidth, pictureHeight);

        int diameter;
        //消息圆圈直径为宽或者高的 1/3
        if(pictureWidth < pictureHeight) {
            diameter = pictureWidth / 3;
        } else {
            diameter = pictureHeight / 3;
        }
        int hideSize = diameter / 20;  //右边和上边隐藏的像素

        graphics2D.drawImage(messageImage, null, (pictureWidth + hideSize - diameter), -hideSize);
    }

    //圆框的bufferedImage, 需要传入显示的消息数, 原图片宽高
    public static BufferedImage getMessageCircle(int messageNum, int pictureWidth, int pictureHeight) {
        String numberStr;

        if(messageNum > 99) {
            numberStr = "99+";
        } else if(messageNum < 0) {
            numberStr = "0";
        } else {
            numberStr = String.valueOf(messageNum);
        }

        int diameter;
        //消息圆圈直径为宽或者高的 1/3
        if(pictureWidth < pictureHeight) {
            diameter = pictureWidth / 3;
        } else {
            diameter = pictureHeight / 3;
        }

        //这样构造的bufferedImage背景是黑色的
        BufferedImage bufferedImage = new BufferedImage(diameter, diameter, BufferedImage.TYPE_3BYTE_BGR);

        Graphics2D g2d = bufferedImage.createGraphics();

        //背景透明的bufferedImage
        bufferedImage = g2d.getDeviceConfiguration().createCompatibleImage(diameter, diameter, Transparency.TRANSLUCENT);

        g2d.dispose();//释放

        //下面开始画消息框
        Graphics2D graphics2D = bufferedImage.createGraphics();

        //先画红色圆圈
        graphics2D.setPaint(Color.RED);
        Ellipse2D ellipse = new Ellipse2D.Double(0, 0, diameter, diameter);
        graphics2D.fill(ellipse);

        //画消息, 消息要画在正中间
        int fontSize = diameter / 2; //字体大小为直径 2/6
        Font font = new Font("SansSerif", Font.PLAIN, fontSize);
        graphics2D.setFont(font);

        //获取包含字符串 numberStr 的矩形, 通过它来获取字符串占的宽高
        FontRenderContext context = graphics2D.getFontRenderContext();
        Rectangle2D bounds = font.getStringBounds(numberStr, context);

        double x = (diameter - bounds.getWidth()) / 2;
        double y = (diameter - bounds.getHeight()) / 2;
        double acsent = -bounds.getY(); //上坡度;

        double baseY = y + acsent;

        //画消息
        graphics2D.setPaint(Color.WHITE);
        graphics2D.drawString(numberStr, (int)x, (int)baseY);

        graphics2D.dispose();

        return bufferedImage;
    }
}


全部评论
点赞!
点赞 回复 分享
发布于 2016-11-28 17:26
给个赞!
点赞 回复 分享
发布于 2016-11-28 17:05
厉害,图像处理算法那一块是比较费时的
点赞 回复 分享
发布于 2016-11-28 14:25
棒!加了精华~~~
点赞 回复 分享
发布于 2016-11-28 09:51
99+怎么弄的。
点赞 回复 分享
发布于 2016-11-27 10:43
整体效果图.. 第一次发帖, 不清楚怎么搞, 发上来的代码好像很乱...
点赞 回复 分享
发布于 2016-11-26 13:42
首次, 程序操作方法: 接下来是结果图片 小图片: 宽高正常图片: 最后一张是苍老师..
点赞 回复 分享
发布于 2016-11-26 13:40

相关推荐

06-15 18:44
黄淮学院 Java
Lynn012:如果是居民楼还是算了吧,看着有点野呢
点赞 评论 收藏
分享
避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
评论
点赞
17
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务