/*
* @author Michael Feng
* @date 2017年9月4日
*/
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ImageUtils {
private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);
/**
*
* @Title: 构造图片
* @Description: 生成水印并返回java.awt.image.BufferedImage
* @param file
* 源文件(图片)
* @param waterFile
* 水印文件(图片)
* @param x
* 距离右下角的X偏移量
* @param y
* 距离右下角的Y偏移量
* @param alpha
* 透明度, 选择值从0.0~1.0: 完全透明~完全不透明
* @return BufferedImage
* @throws IOException
*/
private static BufferedImage watermark(ImageParam param) throws IOException {
// 获取原图
BufferedImage buffImg = null;
if(isHttpFile(param.getSourceImagePath())){
InputStream sis = null;
try{
URL sourceUrl = new URL(param.getSourceImagePath());
sis = sourceUrl.openConnection().getInputStream();
buffImg = ImageIO.read(sis);
}catch(Exception e){
logger.error("读取源文件异常,{}",e);
}finally{
if(sis != null){
sis.close();
}
}
}else{
File file = null;
try{
file = new File(param.getSourceImagePath());
buffImg = ImageIO.read(file);
}catch(Exception e){
logger.error("读取源文件异常,{}",e);
}
}
// 获取二维码
BufferedImage waterImg = null;
if(isHttpFile(param.getQrCodeImagePath())){
InputStream sis = null;
try{
URL sourceUrl = new URL(param.getQrCodeImagePath());
sis = sourceUrl.openConnection().getInputStream();
waterImg = ImageIO.read(sis);
}catch(Exception e){
logger.error("读取二维码异常,{}",e);
}finally{
if(sis != null){
sis.close();
}
}
}else{
File file = null;
try{
file = new File(param.getQrCodeImagePath());
waterImg = ImageIO.read(file);
}catch(Exception e){
logger.error("读取二维码异常,{}",e);
}
}
//按照要求缩放二维码
if(param.getQrWidth() > 0 && param.getQrHeight() > 0){
BufferedImage tag = new BufferedImage(param.getQrWidth(), param.getQrHeight(), BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(waterImg, 0, 0,param.getQrWidth(), param.getQrHeight(), null);
waterImg = tag;
}
//合成图片
try{
int buffWidth = buffImg.getWidth();
int bufHeight = buffImg.getHeight();
// 创建Graphics2D对象,用在底图对象上绘图
Graphics2D g2d = buffImg.createGraphics();
int waterImgWidth = waterImg.getWidth();// 获取层图的宽度
int waterImgHeight = waterImg.getHeight();// 获取层图的高度
// 在图形和图像中实现混合和透明效果
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, param.getAlpha()));
// 绘制
int start = buffWidth- param.getX() - waterImgWidth;
int end = bufHeight- param.getY() - waterImgHeight;
if(start < 0){
logger.error("X 设置过大");
start = 0;
}
if(end < 0){
logger.error("Y 设置过大");
}
g2d.drawImage(waterImg, start, end , waterImgWidth, waterImgHeight, null);
g2d.dispose();// 释放图形上下文使用的系统资源
}catch(Exception e){
logger.error("合成图片字节流异常,{}",e);
}
return buffImg;
}
/**
* 输出水印图片
*
* @param buffImg
* 图像加水印之后的BufferedImage对象
* @param savePath
* 图像加水印之后的保存路径
*/
private static boolean generateWaterFile(BufferedImage buffImg, String savePath) {
if(buffImg == null || StringUtils.isEmpty(savePath)){
return false;
}
boolean rs = false;
int temp = savePath.lastIndexOf(".") + 1;
try {
rs = ImageIO.write(buffImg, savePath.substring(temp), new File(savePath));
} catch (IOException e) {
logger.error("合成图片错误", e);
return false;
}
return rs;
}
/**
* 参数校验
* @param param
* @return
*/
private static boolean checkParam(ImageParam param ){
if(param == null || StringUtils.isEmpty(param.getSourceImagePath()) || StringUtils.isEmpty(param.getQrCodeImagePath())
|| StringUtils.isEmpty(param.getDestinyImagePath())){
return false;
}
return true;
}
/**
* 判断path是否是web请求
* @param path
* @return
*/
private static boolean isHttpFile(String path){
if(!StringUtils.isEmpty(path) && path.toLowerCase().startsWith("http")){
return true;
}
return false;
}
//合成图片
public static boolean mergeImage(ImageParam param){
if(!checkParam(param)){
logger.error("参数不合法!{}",param.toString());
return false;
}
long start = System.currentTimeMillis();
try{
BufferedImage buffImg = watermark(param);
generateWaterFile(buffImg, param.getDestinyImagePath()); // 输出水印图片
}catch(IOException e){
logger.error("合成图片异常,{}",e);
return false;
}
long end = System.currentTimeMillis();
logger.info("合成图片耗时:{},合成地址:",(end - start),param.getDestinyImagePath());
return true;
}
/**
* 画圆形图片,sourcePath是原图片路径,radius是圆形图片的半径
* @param sourcePath 原图片地址,不能为空
* @param destinyPath 目的图片地址,不能为空
* @param radius,不能为负数,为0或者null表示用图片的宽、高最小值做直径
* @return
*/
public static boolean getCircleImage(CircleImageParam param){
if(StringUtils.isEmpty(param.getSourcePath()) || StringUtils.isEmpty(param.getDestinyPath())){
return false;
}
long start = System.currentTimeMillis();
// 获取原图片
BufferedImage waterImg = null;
try{
if(isHttpFile(param.getSourcePath())){
InputStream sis = null;
try{
URL sourceUrl = new URL(param.getSourcePath());
sis = sourceUrl.openConnection().getInputStream();
waterImg = ImageIO.read(sis);
}catch(Exception e){
logger.error("读取原图片异常,{}",e);
}finally{
if(sis != null){
sis.close();
}
}
}else{
File file = null;
try{
file = new File(param.getSourcePath());
waterImg = ImageIO.read(file);
}catch(Exception e){
logger.error("读取原图片异常,{}",e);
}
}
}catch(Exception e){
logger.error("图片转换成圆形失败", e);
return false;
}
//半径有设置时,以设置的半径为主
int width = waterImg.getWidth();
int height = waterImg.getHeight();
int getDiameter = (width < height)?width:height;
if(param.getDiameter() != null && param.getDiameter() > 0){
getDiameter = param.getDiameter();
}
//按照要求缩放图片
BufferedImage tag = new BufferedImage(getDiameter, getDiameter, BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(waterImg, 0, 0,getDiameter, getDiameter, null);
waterImg = tag;
//生成最终的图片
boolean rs = false;
Graphics2D g2 = null;
try {
tag = new BufferedImage(getDiameter, getDiameter, BufferedImage.TYPE_INT_ARGB);
g2 = tag.createGraphics();
g2.setComposite(AlphaComposite.Src);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fill(new RoundRectangle2D.Float(0, 0, getDiameter, getDiameter, getDiameter,getDiameter));
g2.setComposite(AlphaComposite.SrcAtop);
g2.drawImage(waterImg, 0, 0, null);
int temp = param.getDestinyPath().lastIndexOf(".") + 1;
rs = ImageIO.write(tag,param.getDestinyPath().substring(temp), new File(param.getDestinyPath()));
} catch (IOException e) {
logger.error("合成图片错误", e);
return false;
}finally{
if(g2 != null){
g2.dispose();
}
}
long end = System.currentTimeMillis();
logger.info("生成圆角图片耗时:{},图片地址:",(end - start),param.getDestinyPath());
return rs;
}
/**
*
* @param args
* @throws IOException
* IO异常直接抛出了
* @author bls
*/
public static void main(String[] args) throws IOException {
// String sourceFilePath = "https://z0.muscache.com/im/pictures/ec501732-e7bf-47d3-bdbb-cb2e9e5ddd6f.jpg";
String waterFilePath = "https://gss0.bdstatic.com/94o3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=fa9140accd95d143ce7bec711299e967/2934349b033b5bb571dc8c5133d3d539b600bc12.jpg";
String sourceFilePath = "C://image1.jpg";
// String waterFilePath = "C://image2.jpg";
String saveFilePath = "C://new.png";
// ImageParam param = new ImageParam();
// param.setSourceImagePath(sourceFilePath);//底层原图片地址 必传
// param.setQrCodeImagePath(waterFilePath);//二维码图片 必传
// param.setDestinyImagePath(saveFilePath);//目标保存图片路径 必传
// param.setX(10); // 相对底层图片右下角的横轴 像素点 默认为0
// param.setY(100);// 相对底层图片右下角的纵轴 像素点 默认为0
param.setAlpha(0.5f);//二维码图片的透明度,默认为1
// param.setQrWidth(100);//二维码宽度
// param.setQrHeight(50);//二维码高度
//
// boolean rs = ImageUtils.mergeImage(param);
// System.out.println("rs:" + rs);
CircleImageParam circleParam = new CircleImageParam();
circleParam.setSourcePath(sourceFilePath);//可以是网络图片,可是是本地图片
circleParam.setDestinyPath(saveFilePath);//必须是本地图片,且图片格式必须是png
circleParam.setDiameter(300);//图片直径,不指定,则是原图片宽高的最小值
boolean r = ImageUtils.getCircleImage(circleParam);
System.out.println("r:" + r);
}
}
转载于:https://my.oschina.net/liangxiao/blog/1539484