图片的马赛克处理

图片的马赛克处理

原理如下:
图像打码其实也是图像卷积操作中,空间域滤波的一种方式,用一定大小的滤波器对马赛克范围内像素进行操作。实现过程:将需要打马范围按照滤波器大小划分为多个区块,取滤波器范围内像素,求取均值,再将均值赋值给范围内每一个像素,滤波器再滑到下一个区块。

package com.itinspur.demo;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

/**
 * 图像马赛克原理及其实现
 * @program: practice_masaike
 * @author: csl
 * @create: 2021-02-23 09:55
 */
public class MosaicFilter {
    
    

    /**
     * @author: csl
     *对整个图片进行马赛克处理
     *对整张图像打码。对整张图片打码也叫做像素格特效,我们只需要考虑滤波器大小即可。
     * @param image 获取到的图片流对象
     * @param length 设置的马赛克的大小
     */
    public void imageMosaic(BufferedImage image,int length){
    
    

              //从流对象中获取相应图片的信息
        //得到图片的宽度
        int width = image.getWidth();
        //得到图片的高度
        int height = image.getHeight();
        int size = length * length;
        int x= width / length;
        int y=height / length;

        for (int i=0;i<x;i++){
    
    
            for(int j=0;j<y;j++){
    
    
                int R=0,G=0,B=0;
                for(int m=0; m<length; m++){
    
    
                    for(int n=0; n<length; n++){
    
    
                        //Coordinate坐标
                        int xCoordinate = i * length + m;
                        int yCoordinate = j * length + n;
                       /* 应为使用getRGB(i,j)获取的该点的颜色值是ARGB,
                        而在实际应用中使用的是RGB,所以需要将ARGB转化成RGB
                        */
                        int Argb =image.getRGB(xCoordinate,yCoordinate);
                        //相应的位运算符计算
                        // & 如果相对应位都是1,则结果为1,否则为0
                        R += (Argb >> 16) & 0xff;
                        G += (Argb >> 8) & 0xff;
                        B += Argb & 0xff;
                    }
                }
                R = R / size;
                G = G / size;
                B = B / size;
                int RGB = (255 & 0xff) << 24 | (clamp(R) & 0xff) << 16 | (clamp(G) & 0xff) << 8 | (clamp(B) & 0xff);
                for(int m = 0; m < length; m++) {
    
    
                    for(int n = 0; n < length; n++) {
    
    
                        int xCoordinate = i * length + m;
                        int yCoordinate = j * length + n;
                        image.setRGB(xCoordinate, yCoordinate, RGB);
                    }
                }
            }
        }
    }



    /**
     * @author: csl
     * 进行图片的局部马赛克打码
     *局部打码。局部打码需要先定义好打码起始位置,打码范围,马赛克大小。
     * @param image
     * @param xCoordinate 横坐标起始位置
     * @param yCoordinate 纵坐标起始位置
     * @param xLength x方向长度
     * @param yLength y方向长度
     * @param length  马赛克大小
     */
    public void mosaic(BufferedImage image,int xCoordinate,int yCoordinate,int xLength,int yLength,int length) {
    
    
        //逻辑运算符 ||
        if ((xCoordinate + xLength) > image.getWidth() || (yCoordinate + yLength) > image.getHeight()) {
    
    
            System.out.println("马赛克范围大于图像范围!");
            return;
        }
        int size = length * length;
        int x = xLength / length;
        int y = yLength / length;
        for(int m = 0; m < x; m++) {
    
    
            for(int n = 0; n < y; n++) {
    
    
                int R=0,G=0,B=0;
                for(int i = 0; i < length; i++) {
    
    
                    for(int j = 0; j < length; j++) {
    
    
                        int x1 = xCoordinate + m * length + i;
                        int y1 = yCoordinate + n * length + j;
                        int rgb = image.getRGB(x1, y1);
                        R += (rgb >> 16) & 0xff;
                        G += (rgb >> 8) & 0xff;
                        B += rgb & 0xff;
                    }
                }
                R = R / size;
                G = G / size;
                B = B / size;
                int RGB = (255 & 0xff) << 24 | (clamp(R) & 0xff) << 16 | (clamp(G) & 0xff) << 8 | (clamp(B) & 0xff);
                for(int i = 0; i < length; i++) {
    
    
                    for(int j = 0; j < length; j++) {
    
    
                        int x1 = xCoordinate + m * length + i;
                        int y1 = yCoordinate + n * length + j;
                        image.setRGB(x1, y1, RGB);
                    }
                }
            }
        }
    }

    /**
     * @author: csl
     * 判断r,g,b值,大于256返回256,小于0则返回0,0到256之间则直接返回原始值
     * 注意此if语句的写法
     * @param Argb
     * @return
     */
    private int clamp(int Argb){
    
    
        if(Argb > 255)
            return 255;
        if(Argb < 0)
            return 0;
        return Argb;

    }

    public static void main(String[] args) throws IOException {
    
    
       File in = new File("E:/IMG_20180908_181626.jpg");
       File out = new File("E:/IMG_20180908_181626-副本1.jpg");
       BufferedImage image = ImageIO.read(in);
        new MosaicFilter().imageMosaic(image, 100);
        //new MosaicFilter().mosaic(image, 500, 100, 1000, 1700,100);
        ImageIO.write(image, "jpg", out);
    }
}

未进行打码的原图
未进行打码处理的图片
对图片进行全局打码
对图片进行全局打码
对图片进行局部打码处理
对图片进行局部马赛克处理

注意* @author: csl
坐标原点在左上,向右X,向下Y

猜你喜欢

转载自blog.csdn.net/Liamcsl/article/details/113987630