JAVA 实现对图片打码,打马赛克

一. 图片区域类

package com.example.demo.xxx;

/**
 * 图片区域类
 * @author jlm
 *
 */
public class ImageArea {

    int x;	//指定区域左上角横坐标
    int y;	//指定区域左上角纵坐标
    int width;	//指定区域宽度
    int height;	//指定区域高度
    public ImageArea(int x, int y, int width, int height) {
        super();
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
    }
    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public int getY() {
        return y;
    }
    public void setY(int y) {
        this.y = y;
    }
    public int getWidth() {
        return width;
    }
    public void setWidth(int width) {
        this.width = width;
    }
    public int getHeight() {
        return height;
    }
    public void setHeight(int height) {
        this.height = height;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + height;
        result = prime * result + width;
        result = prime * result + x;
        result = prime * result + y;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        ImageArea other = (ImageArea) obj;
        if (height != other.height)
            return false;
        if (width != other.width)
            return false;
        if (x != other.x)
            return false;
        if (y != other.y)
            return false;
        return true;
    }

}

二. 图片绘制工具类

package com.example.demo.xxx;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.imageio.ImageIO;

/**
 * 图片处理类
 * @author hty
 *
 */
public class ImageUtil {
    /**
     * 给图片指定位置打马赛克
     * @param filePath 图片位置
     * @param targetPath 打码后的图片保存位置,若为空则保存路径默认为原图片路径
     * @param x 图片要打码区域左上角的横坐标
     * @param y 图片要打码区域左上角的纵坐标
     * @param width 图片要打码区域的宽度
     * @param height 图片要打码区域的高度
     * @param mosaicSize 马赛克尺寸,即每个矩形的长宽
     * @return
     * @throws IOException
     */
    @SuppressWarnings("static-access")
    public static boolean mosaic(String filePath, String targetPath,
                                 int x, int y, int width, int height, int mosaicSize) throws IOException {
        //1. 初始化图像处理各变量
        if (!filePath.endsWith(".png") && !filePath.endsWith(".jpg") &&
                !filePath.endsWith(".gif")) {
            System.err.println("ImageUtil>>>文件名非法,不是正确的图片文件名");
            return false;
        }
        int index = filePath.lastIndexOf(".");
        String suffix = filePath.substring(index + 1);
        if (targetPath != null && !targetPath.isEmpty() && !targetPath.endsWith(suffix)) {
            System.err.println("ImageUtil>>>目标文件后缀应与源文件后缀一致");
            return false;
        }
        File file = new File(filePath);
        if (!file.isFile()) {
            System.err.println("ImageUtil>>>" + filePath + "不是一个文件!");
            return false;
        }
        BufferedImage bi = ImageIO.read(file); // 读取该图片
        BufferedImage spinImage = new BufferedImage(bi.getWidth(),
                bi.getHeight(), bi.TYPE_INT_RGB);
        if (bi.getWidth() < mosaicSize || bi.getHeight() < mosaicSize || mosaicSize <= 0) { // 马赛克格尺寸太大或太小
            System.err.println("马赛克尺寸设置不正确");
            return false;
        }

        //2. 设置各方向绘制的马赛克块个数
        int xcount = 0; // 方向绘制个数
        int ycount = 0; // y方向绘制个数
        if (width % mosaicSize == 0) {
            xcount = width / mosaicSize;
        } else {
            xcount = width / mosaicSize + 1;
        }
        if (height % mosaicSize == 0) {
            ycount = height / mosaicSize;
        } else {
            ycount = height / mosaicSize + 1;
        }

        //3. 绘制马赛克(绘制矩形并填充颜色)
        Graphics gs = spinImage.getGraphics();
        gs.drawImage(bi, 0, 0, null);
        int xTmp = x;
        int yTmp = y;
        for (int i = 0; i < xcount; i++) {
            for (int j = 0; j < ycount; j++) {
                //马赛克矩形格大小
                int mwidth = mosaicSize;
                int mheight = mosaicSize;
                if(i == xcount - 1){   //横向最后一个比较特殊,可能不够一个size
                    mwidth = width - xTmp;
                }
                if(j == ycount - 1){  //同理
                    mheight = height - yTmp;
                }
                //矩形颜色取中心像素点RGB值
                int centerX = xTmp;
                int centerY = yTmp;
                if (mwidth % 2 == 0) {
                    centerX += mwidth / 2;
                } else {
                    centerX += (mwidth - 1) / 2;
                }
                if (mheight % 2 == 0) {
                    centerY += mheight / 2;
                } else {
                    centerY += (mheight - 1) / 2;
                }
                Color color = new Color(bi.getRGB(centerX, centerY));
                gs.setColor(color);
                gs.fillRect(xTmp, yTmp, mwidth, mheight);
                yTmp = yTmp + mosaicSize;// 计算下一个矩形的y坐标
            }
            yTmp = y;// 还原y坐标
            xTmp = xTmp + mosaicSize;// 计算x坐标
        }
        gs.dispose();
        if (targetPath == null || targetPath.isEmpty())
            targetPath = filePath;
        File sf = new File(targetPath);
        ImageIO.write(spinImage, suffix, sf); // 保存图片
        return true;
    }

    public static boolean mosaic(String filePath, String targetPath,
                                 ImageArea area, int mosaicSize) throws IOException {
        return  mosaic(filePath, targetPath, area.getX(), area.getY(),
                area.getWidth(), area.getHeight(), mosaicSize);
    }

    /**
     * 给图片多个指定位置打马赛克
     * @param filePath 图片位置
     * @param targetPath 打码后的图片保存位置,若为空则保存路径默认为原图片路径
     * @param areaList 图片区域对象数组
     * @param mosaicSize 马赛克尺寸,即每个矩形的长宽
     * @return
     * @throws IOException
     */
    @SuppressWarnings("static-access")
    public static boolean mosaic(String filePath, String targetPath,
                                 List<ImageArea> areaList, int mosaicSize) throws IOException  {
        //1. 初始化图像处理各变量
        if (!filePath.endsWith(".png") && !filePath.endsWith(".jpg") &&
                !filePath.endsWith(".gif")) {
            System.err.println("ImageUtil>>>文件名非法,不是正确的图片文件名");
            return false;
        }
        int index = filePath.lastIndexOf(".");
        String suffix = filePath.substring(index + 1);
        if (targetPath != null && !targetPath.isEmpty() && !targetPath.endsWith(suffix)) {
            System.err.println("ImageUtil>>>目标文件后缀应与源文件后缀一致");
            return false;
        }
        File file = new File(filePath);
        if (!file.isFile()) {
            System.err.println("ImageUtil>>>" + filePath + "不是一个文件!");
            return false;
        }
        BufferedImage bi = ImageIO.read(file); // 读取该图片
        BufferedImage spinImage = new BufferedImage(bi.getWidth(),
                bi.getHeight(), bi.TYPE_INT_RGB);
        if (bi.getWidth() < mosaicSize || bi.getHeight() < mosaicSize || mosaicSize <= 0) { // 马赛克格尺寸太大或太小
            System.err.println("马赛克尺寸设置不正确");
            return false;
        }

        Graphics gs = spinImage.getGraphics();
        gs.drawImage(bi, 0, 0, null);
        //对每一个局部区域分别绘制马赛克
        for (ImageArea imageArea : areaList) {
            int x = imageArea.getX();
            int y = imageArea.getY();
            int width = imageArea.getWidth();
            int height = imageArea.getHeight();
            //2. 设置各方向绘制的马赛克块个数
            int xcount = 0; // 方向绘制个数
            int ycount = 0; // y方向绘制个数
            if (width % mosaicSize == 0) {
                xcount = width / mosaicSize;
            } else {
                xcount = width / mosaicSize + 1;
            }
            if (height % mosaicSize == 0) {
                ycount = height / mosaicSize;
            } else {
                ycount = height / mosaicSize + 1;
            }

            //3. 绘制马赛克(绘制矩形并填充颜色)
            int xTmp = x;
            int yTmp = y;
            for (int i = 0; i < xcount; i++) {
                for (int j = 0; j < ycount; j++) {
                    //马赛克矩形格大小
                    int mwidth = mosaicSize;
                    int mheight = mosaicSize;
                    if(i == xcount - 1){   //横向最后一个比较特殊,可能不够一个size
                        mwidth = width - xTmp;
                    }
                    if(j == ycount - 1){  //同理
                        mheight = height - yTmp;
                    }
                    //矩形颜色取中心像素点RGB值
                    int centerX = xTmp;
                    int centerY = yTmp;
                    if (mwidth % 2 == 0) {
                        centerX += mwidth / 2;
                    } else {
                        centerX += (mwidth - 1) / 2;
                    }
                    if (mheight % 2 == 0) {
                        centerY += mheight / 2;
                    } else {
                        centerY += (mheight - 1) / 2;
                    }
                    Color color = new Color(bi.getRGB(centerX, centerY));
                    gs.setColor(color);
                    gs.fillRect(xTmp, yTmp, mwidth, mheight);
                    yTmp = yTmp + mosaicSize;// 计算下一个矩形的y坐标
                }
                yTmp = y;// 还原y坐标
                xTmp = xTmp + mosaicSize;// 计算x坐标
            }

        }
        gs.dispose();
        if (targetPath == null || targetPath.isEmpty())
            targetPath = filePath;
        File sf = new File(targetPath);
        ImageIO.write(spinImage, suffix, sf); // 保存图片
        return true;
    }
}

三. 实现效果

    try {
            ImageUtil.mosaic("/Users/jianglinmao/Downloads/x.png",
                    "/Users/jianglinmao/Downloads/x1.png", new ImageArea( 200, 400, 300 , 200), 40);
        } catch (IOException e) {
            System.err.println("出错了!!!!");
            e.printStackTrace();
        }

Like  this   (需要已知图片打码位置坐标)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值