问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

图像原理以及如何实现一个马赛克图像

创作时间:
作者:
@小白创作中心

图像原理以及如何实现一个马赛克图像

引用
CSDN
1.
https://blog.csdn.net/2403_89051763/article/details/145260420

马赛克是一种常见的图像处理技术,广泛应用于隐私保护、图像模糊处理等领域。本文将从图像的基本原理出发,详细介绍如何使用Java实现马赛克效果,适合对编程和图像处理感兴趣的读者。

图像原理

在屏幕上

我们在屏幕上看到的图像都是由屏幕上许许多多不同颜色和亮度的灯珠组成的,每个灯珠的颜色都是由电子三原色(红,绿,蓝)所组成的,每种颜色的变化阶梯有256阶(0~255),因此,每个灯珠的颜色就有256^3种,一个1920×1080的屏幕有200万左右的灯珠,每个灯珠就可代表一个像素,通过这些灯珠的不同颜色和亮度,我们就能在屏幕上看到多种图像。

在内存中

在内存中,我们可以用一个int表示像素的数值并将其记录下来。像素值int作为一个像素存储单位,自身内部所占的内存空间是32bit,前8位表示透明度,其次是Red,Green,Blue各占8位,如下图所示:

像素:Red:0255;Green:0255;Blue:0255;透明度:0255

如何实现马赛克

要实现马赛克,我们要先了解下马赛克的原理:

马赛克处理原理

  1. 划分像素区域:在需要添加马赛克的图像区域上,将其划分为一个个较小的正方形或矩形区域,这些区域就是马赛克的基本单元。
  2. 像素信息统一化:对于每个划分好的小区域,取该区域内所有像素的颜色平均值(或其他统计值,如中位数等),然后用这个平均值来代表该区域内所有像素的颜色。例如,一个小区域内有 100 个像素,经过计算这些像素的平均 RGB 值为(128, 128, 128),那么这个小区域内所有像素都将被设置为这个平均颜色,从而使该区域呈现出一种统一的、模糊的效果。
  3. 视觉效果呈现:当图像中所有划分好的小区域都完成上述处理后,从整体上看,原本清晰的图像部分就变成了由这些统一颜色小区域组成的马赛克图案,细节被掩盖,达到隐藏或模糊特定内容的目的。

了解了马赛克的原理后,我们来用Java来实现这个马赛克的效果。

马赛克处理代码

  1. 获取要处理图片的像素数组
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public int[][] getImagePixArr()
{
    String path = "文件地址";//存储图片地址
    File file = new File(path);//创建File对象flie,方便操作文件
    try {
        BufferedImage img = ImageIO.read(file);//读取图片数据
        int w = img.getWidth();//读取图片宽度
        int h = img.getHeight();//读取图片高度
        int[][] arr = new int[w][h];//创建二维数组保存像素信息
        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                arr[i][j] = img.getRGB(i, j);//获取(i,j)位置的RGB值并存入二维数组
            }
        }
        return arr;//将二维数组作为结果返回
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
  1. 编写绘制马赛克图片的方法

在这里我们取每一个小区块最右下角的一块像素作为平均颜色

public void drawMyImage(Graphics g)
{
    int[][] arr = getImagePixArr();//获取二维数组arr的数据
    int w = arr.length;//得到图像的宽
    int h = arr[0].length;//得到图像的高
    for (int i = 0; i < w; i += 10)//遍历像素并绘制
    {
        for (int j = 0; j < h; j += 10)
        {
            int pixNum = arr[i][j];
            Color color = new Color(pixNum);
            g.setColor(color);
            g.fillRect(800 + i, 90 + j, 10, 10);
        }
    }
}
  1. 重写paint方法
public void paint(Graphics g) 
{
    super.paint(g);
    drawMyImage(g);//调用drawMyImage方法
}

完整代码:

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

public class ImageProUI extends JFrame
{
    public void showUI()
    {
        setTitle("图像处理之马赛克");
        setSize(1900, 900);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
    @Override
    public void paint(Graphics g) 
    {
        super.paint(g);
        drawMyImage(g);
    }
    public int[][] getImagePixArr()
    {
        String path = "D:\\picture material\\5f36ac82-1298-47d2-9f9c-a25d1c427689.png";
        File file = new File(path);
        try {
            BufferedImage img = ImageIO.read(file);
            int w = img.getWidth();
            int h = img.getHeight();
            int[][] arr = new int[w][h];
            for (int i = 0; i < w; i++)
            {
                for (int j = 0; j < h; j++) 
                {
                    arr[i][j] = img.getRGB(i, j);
                }
            }
            return arr;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public void drawMyImage(Graphics g)
    {
        int[][] arr = getImagePixArr();
        int w = arr.length;
        int h = arr[0].length;
        // 原图
        for (int i = 0; i < w; i++)
        {
            for (int j = 0; j < h; j++)
            {
                int pixNum = arr[i][j];
                Color color = new Color(pixNum);
                g.setColor(color);
                g.fillRect(150 + i, 90 + j, 1, 1);
            }
        }
        // 马赛克
        for (int i = 0; i < w; i += 10)
        {
            for (int j = 0; j < h; j += 10)
            {
                int pixNum = arr[i][j];
                Color color = new Color(pixNum);
                g.setColor(color);
                g.fillRect(800 + i, 90 + j, 10, 10);
            }
        }
    }
    public static void main(String[] args)
    {
        ImageProUI ipu = new ImageProUI();
        ipu.showUI();
    }
}

效果如图:

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号