package com.ssish.wxmall.common.data;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.plugins.jpeg.JPEGImageWriteParam;
import javax.imageio.stream.ImageOutputStream;
import org.apache.commons.lang3.StringUtils;
/**
* Java 图片生成
*
* @author houzhenghai
* @date 2018年10月19日 下午4:59:35
*/
public class DrawingUtils {
private static float jPEGcompression = 0.75f;// 图片清晰比率
/**
* 图片制作
* @param backImage 背景图地址
* @param srcImage 二维码地址
* @param descImage //生成后的图片
* @param descImageLeft
* @param descImageTop
*/
public static void makeImage(String backImage, String srcImage, String descImage,
int descImageLeft,int descImageTop) {
try {
int offset = 0;
BufferedImage backBufferedImage = ImageIO.read(new URL(backImage));
BufferedImage srcBufferedImage = ImageIO.read(new URL(srcImage));
// 输出图片宽度
int width = backBufferedImage.getWidth() + offset;
// 输出图片高度
int height = backBufferedImage.getHeight() + offset;
BufferedImage descBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D graphics2d = (Graphics2D) descBufferedImage.getGraphics();
graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 往画布上添加图片,并设置边距
graphics2d.drawImage(backBufferedImage, null, 0, 0);
graphics2d.drawImage(srcBufferedImage, null, descImageLeft, descImageTop);
graphics2d.dispose();
// 输出新图片
ImageIO.write(descBufferedImage, backImage.substring(backImage.lastIndexOf(".")+1, backImage.length()), new File(descImage));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* @Description : 将二维码图片和文字生成到一张图片上
* @Param : localFilePath 生成的新图片存放路径
* @Param : originalImg 原图
* @Param : qrCodeImg 二维码地址
* @Param : shareDesc 图片文字
* @return : java.lang.String
* @Author : houzhenghai
* @Date : 2018/8/15
*/
public static ByteArrayOutputStream makeImage(String localFilePath,String originalImg, String qrCodeImg,int qrCodePaddingLeft,int qrCodePaddingTop,int qrCodeWidth,int qrCodeHeight,String shareDesc) throws Exception {
/*
// 加载原图图片
BufferedImage imageLocal = ImageIO.read(new URL(originalImg));
// 加载用户的二维码
BufferedImage imageCode = ImageIO.read(new URL(qrCodeImg));
// 以原图片为模板
Graphics2D g = imageLocal.createGraphics();
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g.setComposite(ac);
g.setBackground(Color.WHITE);
// 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
//g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null);
g.drawImage(imageCode, qrCodePaddingLeft, imageLocal.getHeight() - qrCodePaddingTop, qrCodeWidth, qrCodeHeight, null);
// 设置文本样式
g.setFont(new Font("微软雅黑", Font.PLAIN, 40));
g.setColor(Color.red);
// 计算文字长度,计算居中的x点坐标
//g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530);
// 设置文本样式
g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16));
g.setColor(Color.WHITE);
// 计算文字长度,计算居中的x点坐标
String caewm = "长按二维码";
g.drawString(caewm, 105, imageLocal.getHeight() - 10);
ByteArrayOutputStream out = new ByteArrayOutputStream();
*/
// 加载原图图片
BufferedImage imageLocal = null;
if(StringUtils.isNotBlank(originalImg)&&originalImg.toLowerCase().indexOf("http")!=-1) {
imageLocal = ImageIO.read(new URL(originalImg));
}else {
imageLocal = ImageIO.read(new File(originalImg));
}
// 加载用户的二维码
BufferedImage imageCode = null;
if(StringUtils.isNotBlank(qrCodeImg)&&qrCodeImg.toLowerCase().indexOf("http")!=-1) {
imageCode = ImageIO.read(new URL(qrCodeImg));
}else {
imageCode = ImageIO.read(new File(qrCodeImg));
}
// 以原图片为模板
Graphics2D g = imageLocal.createGraphics();
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g.setComposite(ac);
g.setBackground(Color.WHITE);
// 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
//g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null);
//g.drawImage(imageCode, 100, imageLocal.getHeight() - 50, 43, 43, null);
//加载头像 http://image.ssish.com/uniFolder/476/userAvatar/0.png
/*String headImg="http://image.ssish.com/uniFolder/476/userAvatar/0.png";
BufferedImage headCode = null;
if(StringUtils.isNotBlank(headImg)&&headImg.toLowerCase().indexOf("http")!=-1) {
headCode = ImageIO.read(new URL(headImg));
}else {
headCode = ImageIO.read(new File(headImg));
}
g.drawImage(headCode, 100, imageLocal.getHeight() - 100, 100, 100, null);*/
g.drawImage(imageCode, qrCodePaddingLeft, imageLocal.getHeight() - qrCodePaddingTop, qrCodeWidth, qrCodeHeight, null);
// 设置文本样式
g.setFont(new Font("微软雅黑", Font.PLAIN, 40));
g.setColor(Color.red);
// 计算文字长度,计算居中的x点坐标
g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530);
// 设置文本样式
g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16));
g.setColor(Color.WHITE);
// 计算文字长度,计算居中的x点坐标
/*
String caewm = "长按二维码";
g.drawString(caewm, 105, imageLocal.getHeight() - 10);
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
saveAsJPEG(imageLocal, out);
//FileOutputStream fileOutputStream = new FileOutputStream( new File( "d:/1123.jpg" ) ) ;
//out.writeTo(fileOutputStream) ;
//fileOutputStream.flush();
//out.close();
//return urlImgDownInputStream(FileUtils.parse(out));
FileOutputStream fileOutputStream = new FileOutputStream( new File(localFilePath) ) ;
out.writeTo(fileOutputStream) ;
fileOutputStream.flush();
out.close();
return out;
}
/**
* @Description : 将二维码图片和文字生成到一张图片上
* @Param : originalImg 原图
* @Param : qrCodeImg 二维码地址
* @Param : shareDesc 图片文字
* @return : java.lang.String
* @Author : houzhenghai
* @Date : 2018/8/15
*/
public static String generateImg(String originalImg, String qrCodeImg, String shareDesc) throws Exception {
// 加载原图图片
BufferedImage imageLocal = ImageIO.read(new URL(originalImg));
// 加载用户的二维码
BufferedImage imageCode = ImageIO.read(new URL(qrCodeImg));
// 以原图片为模板
Graphics2D g = imageLocal.createGraphics();
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_GASP);
g.setComposite(ac);
g.setBackground(Color.WHITE);
// 在模板上添加用户二维码(地址,左边距,上边距,图片宽度,图片高度,未知)
//g.drawImage(imageCode, 100, imageLocal.getHeight() - 190, 160, 158, null);
//g.drawImage(imageCode, 100, imageLocal.getHeight() - 50, 43, 43, null);
g.drawImage(imageCode, 760, imageLocal.getHeight() - 340, 300, 300, null);
// 设置文本样式
g.setFont(new Font("微软雅黑", Font.PLAIN, 40));
g.setColor(Color.red);
// 计算文字长度,计算居中的x点坐标
/*
g.drawString(shareDesc, imageLocal.getWidth() - 330, imageLocal.getHeight() - 530);
*/
// 设置文本样式
g.setFont(new Font("微软雅黑", Font.PLAIN + Font.BOLD, 16));
g.setColor(Color.WHITE);
// 计算文字长度,计算居中的x点坐标
/*
String caewm = "长按二维码";
g.drawString(caewm, 105, imageLocal.getHeight() - 10);
*/
ByteArrayOutputStream out = new ByteArrayOutputStream();
saveAsJPEG(imageLocal, out);
FileOutputStream fileOutputStream = new FileOutputStream( new File( "d:/1123.jpg" ) ) ;
out.writeTo(fileOutputStream) ;
fileOutputStream.flush();
out.close();
//return urlImgDownInputStream(FileUtils.parse(out));
return null;
}
public static void mergeImage(String backImage, String srcImage, String descImage) {
try {
int offset = 0;
BufferedImage backBufferedImage = ImageIO.read(new URL(backImage));
BufferedImage srcBufferedImage = ImageIO.read(new URL(srcImage));
// 输出图片宽度
int width = backBufferedImage.getWidth() + offset;
// 输出图片高度
int height = backBufferedImage.getHeight() + offset;
BufferedImage descBufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D graphics2d = (Graphics2D) descBufferedImage.getGraphics();
graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// 往画布上添加图片,并设置边距
graphics2d.drawImage(backBufferedImage, null, 0, 0);
graphics2d.drawImage(srcBufferedImage, null, 175, 175);
graphics2d.dispose();
// 输出新图片
ImageIO.write(descBufferedImage, "png", new File(descImage));
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 以JPEG编码保存图片
*
* @param image_to_save
* 要处理的图像图片
* @param fos
* 文件输出流
* @throws IOException
*/
private static void saveAsJPEG(BufferedImage imageToSave, ByteArrayOutputStream fos) throws IOException {
ImageWriter imageWriter = ImageIO.getImageWritersBySuffix("jpg").next();
ImageOutputStream ios = ImageIO.createImageOutputStream(fos);
imageWriter.setOutput(ios);
if (jPEGcompression >= 0 && jPEGcompression <= 1f) {
// new Compression
JPEGImageWriteParam jpegParams = (JPEGImageWriteParam) imageWriter.getDefaultWriteParam();
jpegParams.setCompressionMode(JPEGImageWriteParam.MODE_EXPLICIT);
jpegParams.setCompressionQuality(jPEGcompression);
}
// new Write and clean up
ImageIO.setUseCache(false);
imageWriter.write(new IIOImage(imageToSave, null, null));
ios.close();
imageWriter.dispose();
}
/**
* 图片流远程上传
*
* @author houzhenghai
* @date 2018年10月19日 下午5:07:24
* @param inStream
* @param imgType
* @return
* @throws Exception
*/
/*
private static String urlImgDownInputStream(InputStream inStream) throws Exception {
String md5 = MD5Utils.MD5(TimeUtils.getTimestamp().toString());
HttpClient httpclient = new DefaultHttpClient();
try {
HttpPost post = new HttpPost(IMG_UPLOAD_PATH);// 文件服务器上传图片地址
MultipartEntity mpEntity = new MultipartEntity();
ContentBody contb = new InputStreamBody(inStream, md5 + ".png");
mpEntity.addPart("Filedata", contb);
post.setEntity(mpEntity);
HttpResponse httpResponse = httpclient.execute(post);
HttpEntity entity = httpResponse.getEntity();
String jsonStr = EntityUtils.toString(entity);
JSONObject ob = JSONObject.fromObject(jsonStr);
if (!ob.isEmpty() && ob.containsKey("pic_id")) {
return ob.getString("pic_id");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
httpclient.getConnectionManager().shutdown();
}
return null;
}
*/
/**
* test
*
* @param args
* @throws
*/
/*
public static void main(String[] args) {
long starttime = System.currentTimeMillis();
System.out.println("开始:" + starttime);
try {
String originalImg = "http://image.run4wd.com/newBee/invitationposter/821806.jpg";
String qrCodeImg = "http://image.run4wd.com/newBee/invitationposter/qrcode/612278_qrcode.jpg";
String shareDesc = "";
String img = generateImg(originalImg, qrCodeImg, shareDesc);
System.out.println("生成完毕,url=" + img);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("结束:" + (System.currentTimeMillis() - starttime) / 1000);
}
*/
public static void main(String[] args) {
long starttime = System.currentTimeMillis();
System.out.println("开始:" + starttime);
/*
//两张图片合成一张
try {
String originalImg = "http://image.ssish.com/newBee/poster/invitation/765029.jpg";
String qrCodeImg = "http://image.ssish.com/uniFolder/476/poster/1586411727926.jpg";
String shareDesc = "d:/33.png";
makeImage(originalImg, qrCodeImg, shareDesc,760,1389);
//System.out.println("生成完毕,url=" + img);
} catch (Exception e) {
e.printStackTrace();
}
*/
//两张图片合成一张并加文字
String[] posterInvitationPositionParamArr = "280,280,760,345,280,280".split(",");
//String localFilePath="/datavg/temp/newimg.png";//生成的新图片放在临时目录下
String localFilePath="d:/test.jpg";//生成的新图片放在临时目录下
String originalImg = "http://image.ssish.com/newBee/poster/invitation/823941.jpg";
String qrCodeImg = "http://image.ssish.com/uniFolder/476/poster/1586411727926.jpg";
try {
ByteArrayOutputStream os=DrawingUtils.makeImage(localFilePath,originalImg, qrCodeImg, Integer.valueOf(posterInvitationPositionParamArr[2]), Integer.valueOf(posterInvitationPositionParamArr[3]), Integer.valueOf(posterInvitationPositionParamArr[4]), Integer.valueOf(posterInvitationPositionParamArr[5]), "张三,欢迎你!");
} catch (Exception e) {
e.printStackTrace();
}
//把生成的新图片上传到服务器,并删除临时目录下的文件
/*String fileName=localFilePath.substring(localFilePath.lastIndexOf("/")+1,localFilePath.length());
ossService.upload(new File(localFilePath),"poster/invitation/"+fileName);
FileUtils.deleteFile(localFilePath);*/
System.out.println("结束:" + (System.currentTimeMillis() - starttime) / 1000);
}
}
合成后的新图片