java 给图片打水印 Plus

java

    之前写了一篇文章,java 给图片打水印,虽然呢,功能是实现了,但是,代码结构混乱、效率低下,还使用到了SUN包下的东西,到服务器Maven打包的时候都打包不了,部门老大看了都看不下去了,忍不住亲自操刀斧正了一番,斧正后的就称呼plus版吧,我测试了下效率,原版是200+ms一张图片,plus版是10+ms,实在是汗颜啊。。。。。。。这里把plus版的贴出来,以后敲代码多借鉴下面的代码思想

import java.awt.Color;

import java.awt.Font;

import java.awt.FontFormatException;

import java.awt.Graphics2D;

import java.awt.Image;

import java.awt.RenderingHints;

import java.awt.font.TextAttribute;

import java.awt.image.BufferedImage;

import java.io.BufferedInputStream;

import java.io.ByteArrayOutputStream;

import java.io.IOException;

import java.io.InputStream;

import java.text.AttributedCharacterIterator;

import java.text.AttributedString;

import java.util.List;

import javax.imageio.ImageIO;

import org.apache.commons.lang.StringUtils;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import com.ttpai.cms.content.model.ImageDeal;

import com.ttpai.cms.content.model.ImageGujia;

import com.ttpai.tfs.TFSClicent;

/**

* 估价文章图片,画图工具类

* 1、不变的做缓存,字体和背景图 。用到的字体size不多可以考虑做缓存,因为Font.deriveFont会再new一个Font,可以减少gc

* 2、图片上传改为直接TFS上传,不往磁盘上写,不但增加IO还很慢

* 3、增加异常处理。如:a)TFS上传异常 b)绘图异常。则返回NULL ,为什么返回空字符串? 区分NULL和“”的含义。

* 4、图片限制最大宽高:1200F, 900F。图片已知大小,去掉多余的调用

* 5、不要用main写测试用例

* 6、根据开闭原则,多考虑给外部提供接口有哪些,其他接口一律屏蔽。

* @author rickycoder

*

*/

public class AppraiseImageUtils {

private static final Logger LOGGER = LoggerFactory.getLogger(AppraiseImageUtils.class);

private static final String IMAGE_URL = "http://pic001.ttpaicdn.com/images/";

private static final String PRICE_UNIT = "万元";// 估价的数字和单位是不同的size,所以需要另外绘画

/**

* 车况很新背景图

*/

private static BufferedImage backgroundImageNew = null;

/**

* 车况良好背景图

*/

private static BufferedImage backgroundImageGood = null;

/**

* 车况一般背景图

*/

private static BufferedImage backgroundImageGeneral = null;

/**

* 成交背景图

*/

private static BufferedImage backgroundImageDeal = null;

private static Font fontBold28 = null;

private static Font fontBold36 = null;

private static Font fontRegular18 = null;

private static Font fontRegular20 = null;

static {

try {

backgroundImageNew =

ImageIO.read(AppraiseImageUtils.class

.getResourceAsStream("/appraise/appraise_background_new.png"));

backgroundImageGood =

ImageIO.read(AppraiseImageUtils.class

.getResourceAsStream("/appraise/appraise_background_good.png"));

backgroundImageGeneral =

ImageIO.read(AppraiseImageUtils.class

.getResourceAsStream("/appraise/appraise_background_general.png"));

backgroundImageDeal =

ImageIO.read(AppraiseImageUtils.class

.getResourceAsStream("/appraise/background_deal.png"));

} catch (IOException e) {

LOGGER.error("加载背景图报错", e);

}

InputStream is = null;

BufferedInputStream bis = null;

Font definedFont = null;

try {

is = AppraiseImageUtils.class.getResourceAsStream("/font/PingFang_Bold.ttf");

bis = new BufferedInputStream(is);

definedFont = Font.createFont(Font.TRUETYPE_FONT, bis);

fontBold28 = definedFont.deriveFont(28f);

fontBold36 = definedFont.deriveFont(36f);

is = AppraiseImageUtils.class.getResourceAsStream("/font/PingFang_SC_Regular.otf");

bis = new BufferedInputStream(is);

definedFont = Font.createFont(Font.TRUETYPE_FONT, bis);

fontRegular18 = definedFont.deriveFont(18f);

fontRegular20 = definedFont.deriveFont(20f);

is.close();

bis.close();

} catch (FontFormatException e) {

LOGGER.error("字体格式报错", e);

} catch (IOException e) {

LOGGER.error("加载字体格式报错", e);

} finally {

is = null;

bis = null;

}

definedFont = null;

}

private AppraiseImageUtils() {}

/**

* @Description: 上传图片到TFS

* @param out 图片数据流

* @return String

* @by: yan.zhang@2017年12月15日

*/

private static String uploadImage(ByteArrayOutputStream out) {

if (null == out || 0 == out.size()) {

return null;

}

// 设置图片上传至服务器的配置并上传

TFSClicent tfsClicent = new TFSClicent();

String address = null;

try {

address = IMAGE_URL + tfsClicent.uploadImage(out.toByteArray());

} catch (Exception e) {

LOGGER.error("图片上传失败", e);

}

return address;

}

/**

* @Description:填充文字到图片上(成交列表)

* @param inImagePath

* @param outImagePath

* @param deals

* @return String 返回TFS上的图片地址

* @by: yan.zhang@2017年12月14日

*/

public static String createDealImage(List<ImageDeal> deals) {

Image image = backgroundImageDeal;

int width = image.getWidth(null);

int height = image.getHeight(null);

BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics2D g = bImage.createGraphics();

g.setColor(Color.black);

g.setBackground(Color.white);

/* 画出图片 */

g.drawImage(image, 0, 0, null);

Color color = new Color(102, 102, 102);

/** 下面代码的参数都是根据UED的图片用尺子量的,不会产生魔数,请不要codeReview **/

int x1 = 75;

int x2 = 248;

int x3 = 427;

int x4 = 630;

int y = 90;// 递增48

for (int i = 0; i < deals.size(); i++) {

ImageDeal deal = deals.get(i);

addWord2image(g, deal.getDealCity(), x1, y, fontRegular18, color);// 成交城市

addWord2image(g, DateUtils.formatDateS(deal.getCardTime()), x2, y, fontRegular18, color);// 上牌时间

addWord2image(g, DateUtils.formatDateS(deal.getDealTime()), x3, y, fontRegular18, color);// 成交时间

if (deal.getDealPrice().length() == 6) {// 若是99.99万,则坐标向左挪19个单位

addWord2image(g, deal.getDealPrice(), x4 - 35, y, fontRegular18, color);// 成交价格

} else if (deal.getDealPrice().length() == 5) {// 若是99.9万,则坐标向左挪14个单位

addWord2image(g, deal.getDealPrice(), x4 - 25, y, fontRegular18, color);// 成交价格

} else if (deal.getDealPrice().length() == 4) {// 若是9.9万,则坐标向左挪44个单位

addWord2image(g, deal.getDealPrice(), x4 - 7, y, fontRegular18, color);// 成交价格

} else if (deal.getDealPrice().length() == 3) {// 若是99万,则坐标向左挪44个单位

addWord2image(g, deal.getDealPrice(), x4 - 10, y, fontRegular18, color);// 成交价格

} else {

addWord2image(g, deal.getDealPrice(), x4, y, fontRegular18, color);// 成交价格

}

y += 48;

}

g.dispose();// 画笔结束

ByteArrayOutputStream out = new ByteArrayOutputStream();

try {

ImageIO.write(bImage, "jpg", out);

String imageUrl = uploadImage(out);

out.close();

return imageUrl;

} catch (Exception e) {

LOGGER.error("createDealImage" + e.getMessage(), e);

}

return null;

}

/**

* 创建车况很新的估价图

*

* @param vo

* @return

*/

public static String createGujiaNewImage(ImageGujia vo) {

return createGujiaImage(backgroundImageNew, vo);

}

/**

* 创建车况良好的估价图

*

* @param vo

* @return

*/

public static String createGujiaGoodImage(ImageGujia vo) {

return createGujiaImage(backgroundImageGood, vo);

}

/**

* 创建车况一般的估价图

*

* @param vo

* @return

*/

public static String createGujiaGeneralImage(ImageGujia vo) {

return createGujiaImage(backgroundImageGeneral, vo);

}

/**

* @Description:填充文字到图片上(估价页)

* @param backgroundImage 背景图

* @param vo 图片参数实体

* @return String 返回TFS上的图片地址

* @by: yan.zhang@2017年12月14日

*/

private static String createGujiaImage(BufferedImage backgroundImage, ImageGujia vo) {

Image image = backgroundImage;

int width = image.getWidth(null);

int height = image.getHeight(null);

BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

Graphics2D g = bImage.createGraphics();

g.setColor(Color.black);

g.setBackground(Color.white);

/* 画出图片 */

g.drawImage(image, 0, 0, null);

/** 下面代码的参数都是根据UED的图片用尺子量的,不会产生魔数,请不要codeReview **/

Color color = new Color(51, 51, 51);// 大标题颜色

if (vo.getTitle().length() <= 32) {// 标题字小于32,则用planA

addWord2image(g, vo.getTitle(), 10, 62, fontBold28, color);// 标题

} else {

String titleLine1 = vo.getTitle().substring(0, 32);

addWord2image(g, titleLine1, 10, 41, fontBold28, color);// 标题

String titleLine2 = vo.getTitle().substring(32);

addWord2image(g, titleLine2, 10, 78, fontBold28, color);// 标题

}

color = new Color(81, 81, 81);// 行2文字的颜色 20 35

addWord2image(g, vo.getCity(), 80, 120, fontRegular20, color);// 城市

addWord2image(g, vo.getCarAge(), 200, 120, fontRegular20, color);// 车龄

addWord2image(g, vo.getMileAge(), 310, 120, fontRegular20, color);// 里程

color = new Color(253, 96, 63);// 估价和估价单位的颜色

addWord2image(g, vo.getGujia(), 60, 243, fontBold36, color);// 估价

addWord2image(g, PRICE_UNIT, 156, 243, fontRegular20,color);//估价的单位,估价的数字和单位是不同的size,所以需要另外绘画

color = new Color(167, 167, 167);// 指导价的颜色

addWord2image(g, vo.getGuidancePrice(), 327, 243, fontRegular20, color);// 指导价

g.dispose();// 画笔结束

ByteArrayOutputStream out = new ByteArrayOutputStream();

try {

ImageIO.write(bImage, "jpg", out);

String imageUrl = uploadImage(out);

out.close();

return imageUrl;

} catch (Exception e) {

LOGGER.error("createGujiaImage" + e.getMessage(), e);

}

return null;

}

/**

* @Description: 把文字绘画到图片上,绘画内容为空就不画了。

* @param g Graphics2D

* @param addWord 要加上去的文字

* @param x 横坐标

* @param y 纵坐标

* @param font 字的类型

* @param color 字的颜色 void

* @by: yan.zhang@2017年12月14日

*/

private static void addWord2image(Graphics2D g, String addWord, int x, int y, Font font,

Color color) {

// 绘画内容为空就不画了。

if (StringUtils.isBlank(addWord)) {

return;

}

AttributedString ats = new AttributedString(addWord);

g.setFont(font);

g.setColor(color);

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

ats.addAttribute(TextAttribute.FONT, font, 0, addWord.length());

AttributedCharacterIterator iter = ats.getIterator();

g.drawString(iter, x, y);

}

}

以上是 java 给图片打水印 Plus 的全部内容, 来源链接: utcz.com/z/390557.html

回到顶部