Java将图片处理成背景透明的圆形图片



/*
 * @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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值