一、本图片生成器具有以下功能特性:
1、可以设置图片的宽度、高度、外框颜色、背景色;
2、可以设置图片字体的大小、名称、颜色;
3、可以设置输出图片的格式,如JPEG、GIF等;
4、可以将图片存储到一个文件或者存储到一个输出流;
5、可以为图片增加若干条干扰线(在生成随机码图片时可用此特性);
6、打印在图片上的文字支持自动换行;
7、可以将文字旋转指定弧度数;
二、下面列出相关的源代码
1、抽象类AbstractImageCreator的源代码
/**
* 模板方法模式应用:图片生成器
*/
public abstract class AbstractImageCreator {
private static Random rnd = new Random(new Date().getTime());
private Drawer drawer;
//图片宽度
private int width = 200;
//图片高度
private int height = 80;
//外框颜色
private Color rectColor;
//背景色
private Color bgColor;
//干扰线数目
private int lineNum = 0;
//图片格式
private String formatName = "JPEG";
//字体颜色
private Color fontColor = new Color(0, 0, 0);
//字体名称
private String fontName = "宋体";
//字体大小
private int fontSize = 15;
//文字旋转的弧度数
private double radian = 0;
private double rotateX = 0;
private double rotateY = 0;
//缩放
private double scale = 1;
//##### 此处省略getter、setter方法 #####
public AbstractImageCreator(Drawer drawer){
this.drawer = drawer;
}
/**
* 画干扰线
*/
private void drawRandomLine(Graphics graph){
for(int i=0;i<lineNum;i++){
//线条的颜色
graph.setColor(getRandomColor(100, 155));
//线条两端坐标值
int x1 = rnd.nextInt(width);
int y1 = rnd.nextInt(height);
int x2 = rnd.nextInt(width);
int y2 = rnd.nextInt(height);
//画线条
graph.drawLine(x1, y1, x2, y2);
}
}
/**
* 随机获取颜色对象
*/
private Color getRandomColor(int base, int range){
if((base + range) > 255) range = 255 - base;
int red = base + rnd.nextInt(range);
int green = base + rnd.nextInt(range);
int blue = base + rnd.nextInt(range);
return new Color(red, green, blue);
}
public void generateImage(String text)throws IOException{
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
if(rectColor == null) rectColor = new Color(0, 0, 0);
if(bgColor == null) bgColor = new Color(240, 251, 200);
//获取画布
Graphics2D g = (Graphics2D)image.getGraphics();
//画长方形
g.setColor(bgColor);
g.fillRect(0, 0, width, height);
//外框
g.setColor(rectColor);
g.drawRect(0, 0, width-1, height-1);
//画干扰线
drawRandomLine(g);
//画字符串
drawer.draw(this, g, text);
//执行
g.dispose();
//输出图片结果
saveImage(image);
}
protected abstract void saveImage(BufferedImage image)throws IOException;
}
2、类FileImageCreator的源代码
该类将生成的图片存储到一个文件中,需要设置fileName成员变量值,该成员变量值表示图片的存储全路径。
public class FileImageCreator extends AbstractImageCreator {
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public FileImageCreator(Drawer drawer){
super(drawer);
}
public FileImageCreator(Drawer drawer, String fileName){
super(drawer);
this.fileName = fileName;
}
@Override
protected void saveImage(BufferedImage image)throws IOException{
ImageIO.write(image, getFormatName(), new File(fileName));
}
}
3、类StreamImageCreator的源代码
该类将生成的图片存储到一个输出流中,需要设置stream成员变量值。
public class StreamImageCreator extends AbstractImageCreator {
private OutputStream stream;
public OutputStream getStream() {
return stream;
}
public void setStream(OutputStream stream) {
this.stream = stream;
}
public StreamImageCreator(Drawer drawer){
super(drawer);
}
public StreamImageCreator(Drawer drawer, OutputStream stream){
super(drawer);
this.stream = stream;
}
@Override
protected void saveImage(BufferedImage image) throws IOException {
ImageIO.write(image, getFontName(), stream);
}
}
4、Drawer接口源码
public interface Drawer {
/**
* 在绘画板上绘制字符串
*
* @param creator 图片创建器对象
* @param g 绘画板
* @param text 待绘制的字符串
*/
public void draw(AbstractImageCreator creator, Graphics2D g, String text);
}
5、SimpleDrawer类源码
public class SimpleDrawer implements Drawer {
public void draw(AbstractImageCreator creator, Graphics2D g, String text){
//文字旋转
g.rotate(Math.toRadians(creator.getRadian()), creator.getRotateX(), creator.getRotateY());
g.scale(creator.getScale(), creator.getScale());
g.setColor(creator.getFontColor());
Font font = new Font(creator.getFontName(), Font.PLAIN, creator.getFontSize());
g.setFont(font);
FontMetrics fm = g.getFontMetrics(font);
int fontHeight = fm.getHeight(); //字符的高度
int offsetLeft = 0;
int rowIndex = 1;
for(int i=0;i<text.length();i++){
char c = text.charAt(i);
int charWidth = fm.charWidth(c); //字符的宽度
//另起一行
if(Character.isISOControl(c) || offsetLeft >= (creator.getWidth()-charWidth)){
rowIndex++;
offsetLeft = 0;
}
g.drawString(String.valueOf(c), offsetLeft, rowIndex * fontHeight);
offsetLeft += charWidth;
}
}
}
三、实例代码
public class Test {
public static void main(String[] args) {
try{
StringBuffer sb = new StringBuffer();
sb.append("中华人民共和国\n");
sb.append("中华人民共和国\n");
FileImageCreator creator = new FileImageCreator(new SimpleDrawer(), "c:\\img.jpeg");
creator.setWidth(150); //图片宽度
creator.setHeight(100); //图片高度
creator.setLineNum(20); //干扰线条数
creator.setFontSize(18); //字体大小
creator.setFontName("黑体");
//文字旋转
creator.setRadian(30.0); //旋转弧度
creator.setRotateX(creator.getWidth()/5);
creator.setRotateY(creator.getHeight()*5/10);
creator.generateImage(sb.toString());
System.out.println("ok");
}catch(IOException ex){
ex.printStackTrace();
}
}
}