需要注意 jdk8对PNG的转换有BUG,会很慢.需要升级JDK或者添加JDK9的增强包.解决JDK8转换PNG慢的问题
/**
* 给图片指定位置打马赛克
*
* @param x 图片要打码区域左上角的横坐标
* @param y 图片要打码区域左上角的纵坐标
* @param width 图片要打码区域的宽度
* @param height 图片要打码区域的高度
* @param mosaicSize 马赛克尺寸,即每个矩形的长宽
*/
public static void 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;
}
//2. 设置各方向绘制的马赛克块个数
// x方向绘制个数
int xcount = width / mosaicSize;
// y方向绘制个数
int ycount = height / mosaicSize;
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;
//横向最后一个比较特殊,可能不够一个size
if (i == xcount - 1) {
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);
// 计算下一个矩形的y坐标
yTmp += mosaicSize;
}
// 还原y坐标
yTmp = y;
// 计算x坐标
xTmp += mosaicSize;
}
gs.dispose();
// 保存图片
ImageIO.write(spinImage, SuffixConsts.PNG, target);
}