首先, 其实应该把标题改为——给任意图片右上角套上红色消息数目框;
代码如下:
//主程序:
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;
}
}