记录:java批量生成图片的问题
1.linux安装字体
以微软雅黑为例,找到msyh.ttf ,copy至下面的文件夹
2.drawString 部分代码
以微软雅黑为例,找到msyh.ttf ,copy至下面的文件夹
usr/share/fonts/msyh
执行命令:fc-cache -fv
重启jvm即可
2.drawString 部分代码
private static BufferedImage drawString(int type, boolean isWhite,
int width, int height, String price, Font font_money, Font font,
Graphics2D g2d, Rectangle2D bounds, Rectangle2D bounds_money) {
BufferedImage image;
//透明背景
image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image.createGraphics();
//反锯齿字体
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if(!isWhite){
//非白字
g2d.setColor(new Color(236,0,137));
}else{
//白字
g2d.setColor(new Color(255,255,255));
}
//字体居中
double y = (height - bounds.getHeight()) / 2;
double ascent = -bounds.getY();
double baseY = y + ascent;
g2d.setStroke(new BasicStroke(1));
g2d.setFont(font_money);
g2d.drawString(FONT_RMB_CHAR, -2, (int)baseY);
g2d.setFont(font);
g2d.drawString(price, (int)bounds_money.getWidth()-4, (int)baseY);
g2d.dispose();
return image;
}
int width, int height, String price, Font font_money, Font font,
Graphics2D g2d, Rectangle2D bounds, Rectangle2D bounds_money) {
BufferedImage image;
//透明背景
image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g2d.dispose();
g2d = image.createGraphics();
//反锯齿字体
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if(!isWhite){
//非白字
g2d.setColor(new Color(236,0,137));
}else{
//白字
g2d.setColor(new Color(255,255,255));
}
//字体居中
double y = (height - bounds.getHeight()) / 2;
double ascent = -bounds.getY();
double baseY = y + ascent;
g2d.setStroke(new BasicStroke(1));
g2d.setFont(font_money);
g2d.drawString(FONT_RMB_CHAR, -2, (int)baseY);
g2d.setFont(font);
g2d.drawString(price, (int)bounds_money.getWidth()-4, (int)baseY);
g2d.dispose();
return image;
}
3.如果需要根据字符串的长度生成图片的宽度,可以使用如下方法
Rectangle2D bounds = font.getStringBounds(price, context);
width = (int)(bounds.getWidth();
4.批量生成,使用java自带的线程池,并使用CompletionService,目的是在线程处理结束后得到生成成功的ProductId
width = (int)(bounds.getWidth();
4.批量生成,使用java自带的线程池,并使用CompletionService,目的是在线程处理结束后得到生成成功的ProductId
public boolean generateImagesBatch(){
boolean flag=true;
ExecutorService exec = Executors.newFixedThreadPool(8);
CompletionService<CallBack> completionService=
new ExecutorCompletionService<CallBack>(exec);
long startTime=System.currentTimeMillis();
String sql="select productId,price from prod";
List<Map> skuList = this.cmsJdbcTemplate.queryForList(sql);
for(Map map:skuList){
String prodId=((BigDecimal)map.get("productId")).toString();
double price=((BigDecimal)map.get("price")).doubleValue();
completionService.submit(new CreateImageConcurrent(prodId,price,FontEnum.ONE,false));
completionService.submit(new CreateImageConcurrent(prodId,price,FontEnum.TWO,false)); }
long endTime=System.currentTimeMillis()-startTime;
log.info("query db time>>>>>>>>>>>>>>"+endTime/1000);
Future<CallBack> future;
int count=skuList.size()*6;
log.info("generateImagesBatch count:"+count);
try {
while(count>0){
future = completionService.take();
CallBack callBack = future.get();
if(null!=callBack){
count--; log.info("generateImagesBatch prod id:"+callBack.getSuccesMessage()); }
}
endTime=System.currentTimeMillis()-startTime;
log.info("create images time>>>>>>>>>>>>>>"+endTime/1000);
log.info("generateImagesBatch success!");
flag=true;
} catch (ExecutionException e) {
flag=false;
log.error("generateImagesBatch fail::ExecutionException::"+e.getMessage());
} catch (InterruptedException e) {
flag=false;
log.error("generateImagesBatch fail::InterruptedException::"+e.getMessage());
}finally{
exec.shutdown();
}
return flag;
}
boolean flag=true;
ExecutorService exec = Executors.newFixedThreadPool(8);
CompletionService<CallBack> completionService=
new ExecutorCompletionService<CallBack>(exec);
long startTime=System.currentTimeMillis();
String sql="select productId,price from prod";
List<Map> skuList = this.cmsJdbcTemplate.queryForList(sql);
for(Map map:skuList){
String prodId=((BigDecimal)map.get("productId")).toString();
double price=((BigDecimal)map.get("price")).doubleValue();
completionService.submit(new CreateImageConcurrent(prodId,price,FontEnum.ONE,false));
completionService.submit(new CreateImageConcurrent(prodId,price,FontEnum.TWO,false)); }
long endTime=System.currentTimeMillis()-startTime;
log.info("query db time>>>>>>>>>>>>>>"+endTime/1000);
Future<CallBack> future;
int count=skuList.size()*6;
log.info("generateImagesBatch count:"+count);
try {
while(count>0){
future = completionService.take();
CallBack callBack = future.get();
if(null!=callBack){
count--; log.info("generateImagesBatch prod id:"+callBack.getSuccesMessage()); }
}
endTime=System.currentTimeMillis()-startTime;
log.info("create images time>>>>>>>>>>>>>>"+endTime/1000);
log.info("generateImagesBatch success!");
flag=true;
} catch (ExecutionException e) {
flag=false;
log.error("generateImagesBatch fail::ExecutionException::"+e.getMessage());
} catch (InterruptedException e) {
flag=false;
log.error("generateImagesBatch fail::InterruptedException::"+e.getMessage());
}finally{
exec.shutdown();
}
return flag;
}