简介
今天看到其他图片处理工具的打码功能,就想使用java实现一下,可以对指定区域打码。
实现
原图
打码后的图
代码实现
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
/**
* 图片处理类 支持局部打码
*/
public class ImageUtil {
/**
* 给图片指定位置打马赛克
*
* @param x 图片要打码区域左上角的横坐标
* @param y 图片要打码区域左上角的纵坐标
* @param width 图片要打码区域的宽度
* @param height 图片要打码区域的高度
* @param mosaicSize 马赛克尺寸,即每个矩形的长宽
*/
public static boolean mosaic(InputStream source, OutputStream target,
int x, int y, int width, int height, int mosaicSize) throws IOException {
//读取该图片
BufferedImage bi = ImageIO.read(source);
//复制一份画布,在新画布上作画,因为要用到原来画布的颜色信息
BufferedImage spinImage = new BufferedImage(bi.getWidth(),
bi.getHeight(), BufferedImage.TYPE_INT_RGB);
//马赛克块大小 不能大于图片宽度和高度
if (mosaicSize > bi.getWidth() || mosaicSize > bi.getHeight() || mosaicSize <= 0) {
System.err.println("马赛克尺寸设置不正确");
return false;
}
//2. 设置各方向绘制的马赛克块个数
int xcount = width / mosaicSize; // x方向绘制个数
int ycount = height / mosaicSize; // y方向绘制个数
if ((width % mosaicSize) != 0) {
xcount++;
}
if ((height % mosaicSize) != 0) {
ycount++;
}
//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 += mosaicSize;// 计算下一个矩形的y坐标
}
yTmp = y;// 还原y坐标
xTmp += mosaicSize;// 计算x坐标
}
gs.dispose();
ImageIO.write(spinImage, "jpg", target); // 保存图片
return true;
}
}
客户端使用
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
try {
ImageUtil.mosaic(new FileInputStream("D:/testjar/aaa.jpg"),
new FileOutputStream("D:/testjar/aaa_mosaic.jpg"), 400, 500, 200, 200, 10);
} catch (IOException e) {
System.err.println("出错了!!!!");
e.printStackTrace();
}
}
}
原理
以上面代码中的区域为例,横坐标400,纵坐标500,宽高都为200的一个正方形,用边长为10的马赛克块填充,
颜色使用原图中马赛克块中心位置的RGB颜色。总结来说就是将马赛克块中心位置的颜色扩展到整个马赛克块。