java实现对图片打马赛克

简介

今天看到其他图片处理工具的打码功能,就想使用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颜色。总结来说就是将马赛克块中心位置的颜色扩展到整个马赛克块。

参考

Java实现给图片局部打马赛克
一个在线给图片打码的网站

posted @ 2022-02-08 22:36  strongmore  阅读(1054)  评论(0编辑  收藏  举报