用java实现简单的图像处理基础篇之实现几种滤镜

目录

前言

读取图片

获取路径 

存入图片

 编写代码获取图片路径

几种滤镜的原理

原图(Original Image)

油画 (Oil Painting)

马赛克(Mosaic)

圆点马赛克

灰度(Grayscale)

总结

前言

       java是一种功能强大且广泛使用的编程语言,因其具有丰富的图像处理库面向对象特性强大的社区支持更方便的性能优化,这使得java可以实现图像滤镜。

读取图片

获取路径 

存入图片

       首先选择一张图片信息相对大一些的图片,先存在本地电脑里。然后打开IDEA,在初始模块Pro23中新建一个模块,我们取名为:image,然后将图片复制到这个image模块中。

 编写代码获取图片路径

public int[][] getImagePix(){
   // imgs/kj.jpg
   //定义图片路径
   String path = "image/backiee-25830.jpg";
   // 创建一个文件对象
   File file = new File (path);
   // 打印相关信息
   System.out.println (file.getPath ());
   System.out.println (file.getName ());
   System.out.println (file.getParent ());
   // 判断文件是否存在
   boolean exists = file.exists ();
   if(exists){
   System.out.println ("exists");
   } else{
   System.out.println ("un exists");
   }
   // 声明数组与缓存图
   int[][] imgArray = null;
   BufferedImage buffimg = null;
   try {
    // 基于这个文件对象 进行数据操作时 读取这个文件中的数据 或者向这个文件中写入数据
    // 通过ImageIO类读取图片 存入 buffimg 中
    buffimg = ImageIO.read (file);
    int w = buffimg.getWidth ();
    int h = buffimg.getHeight ();
    // 创建一个二维数组
    imgArray = new int[w][h];
    // 遍历循环 将buffimge中的像素值取出存入二维数组中
    for(int i = 0; i < w; i++){
     for(int j = 0; j < h; j++){
     imgArray[i][j] = buffimg.getRGB (i, j);
     }
    }
    } catch (IOException e) {
      throw new RuntimeException (e);
    }
    // 返回存储好数据值的二维数组
   return imgArray;
}
  • 首先我们要准备把像素信息存储在一个二维数组中,所以方法的返回值我们设定为int类型的二维数组。
  • 用String path="imgs/kj2.png";,这行代码定义了图片文件的路径,引号内的字符串内容就是这张图片的路径,即来自内容根的路径
  • 创建一个文件对象:File file=new File(path);通过传入图片路径,创建一个与图片文件相关联的File对象。当然,别忘了在类之前导入:import java.io.*;。
  • 可以通过方法exist()判断文件是否存在。
  • 声明一个整型二维数组int[][] imageArray用于存储图片的像素信息和一个BufferedImage对象buffimg,用于存储图片的像素信息。这里将它们初始化为 null 是为了确保在 try-catch 语句块之外,它们也能被访问和使用。
  • 使用try-catch语句捕获可能发生的IOException异常。如果发生异常,将抛出一个运行时异常。

几种滤镜的原理

原图(Original Image)

       原图是一种不进行任何处理的图像显示方式。原图保留了图像的所有信息,颜色和细节。在计算机中,通常使用RGB色彩模式表示。

public void OriginalFilter(Graphics g){
        BufferedImage buffimg=new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_RGB);
        System.out.println ("缓存图片存储开始");
        for(int i = 0; i < pixelsArray.length; i++){
            for(int j = 0; j < pixelsArray[i].length; j++){
                int pix = pixelsArray[i][j];
                buffimg.setRGB(i,j,pix);
            }
        }
  • 创建一个名为OriginalFilter的方法,接受一个来自Graphics类型的参数g(这里Graphics已经写在其他类中,我会在后续编写界面和监听器的代码中写到出处)。
  • 创建一个新的BufferedImage对象buffimg。每个对象的宽度和高度与原始图像(image)相同,且类型为BufferedImage.TYPE_INT_RGB,表示每个像素由一个整数值表示,包括红、绿、蓝三个颜色通道。这样可以实现图片快速绘制。
  • 使用两个嵌套的for循环遍历整个pixelArray。外部循环(i)遍历每一行,内部循环(j)遍历每一列,这样就确保二维数组的每一个元素都会被访问到。

这里我想说明一下buffimg.setRGB(i,j,pix)中参数的含义:

  • i表示图片的x坐标,是像素数组pixelsArray的第一维,即宽度方向上的索引,也就是图片中的列;同理j表示图片的y坐标,是像素数组pixelsArray的第二维,即高度方向上的索引。
  • pix表示像素的颜色值。在这个例子中,pix从pixelsArray数组中取得颜色值。

这个方法的主要思想是将二维数组pixelsArray转换到一个BufferedImage对象上。下面是效果。

油画 (Oil Painting)

       油画滤镜模拟了真实油画的效果,将图像中的色彩和纹理进行特殊处理,形成油画风格的图像。实现油画的方式有很多,本文介绍一种常用的方法,即在图像上绘制随即大小的椭圆形。

    public void OilFilter(Graphics g){
        Random ran=new Random();
        for(int i = 0; i < pixelsArray.length; i += 3){
            for(int j = 0; j < pixelsArray[i].length; j += 3){
                int pix = pixelsArray[i][j];
                g.setColor (new Color (pix));
                g.fillOval (i, j, ran.nextInt (8) + 2, ran.nextInt (8) + 5);
            }
        }
    }
  • 首先创建一个Random类的对象ran,用于代表后续我生成的随机数。
  • 利用嵌套的循环语句遍历图片的像素点,和原图的区别是每次增加3个像素点,最终在每个像素点上绘制一个填充椭圆。
  • ran.nextInt(8)+2是一个随机数生成的表达式,它将生成一个介于2到9之间的随机整数,(8)表示:0到7之间随机生成一个整数,+2表示将随机数的范围从2到9进行了转换。

总之油画滤镜的方法实现逻辑和原图大同小异,下面是效果展示。

马赛克(Mosaic)

       马赛克也是一种常见的图像处理技术,它的原理是:先将图像分为许多个小的矩形区域,然后用这些区域内的代表像素的颜色值替换整个矩形区域。马赛克滤镜常用于隐藏图像或视频中的敏感信息或创造一种特定的艺术风格。

    public void MosaicFilter(Graphics g){
        for(int i = 0; i < pixelsArray.length; i += 10){
            for(int j = 0; j < pixelsArray[i].length; j += 10){
                int pix = pixelsArray[i][j];
                g.setColor (new Color (pix));
                g.fillRect (i, j, 10, 10);
            }
        }
    }
  • 接收一个Graphics对象作为参数,该对象用于处理和绘制图像。
  • 通过嵌套循环,遍历pixelsArray二维数组,相比原图绘制,每次循环对i和j变量递增的值变大,这里设置为10,这样就可以实现提取相隔较远的像素点。所以这种方法是依赖于马赛克块的大小和像素跳过的数量

总之马赛克效果是基于原图绘制的原理而来的。效果如下。

圆点马赛克

圆点马赛克通常是指使用圆形元素覆盖在图像上,将图像分解成一系列圆点来创建一种视觉效果。实际上,圆点马赛克和上文的马赛克的区别仅仅在于矩形和圆形的区别,所以这里就简单介绍即可。

    public void CircleMosaicFilter(Graphics g){
        for(int i = 0; i < pixelsArray.length; i += 10){
            for(int j = 0; j < pixelsArray[i].length; j += 10){
                int pix = pixelsArray[i][j];
                bg.setColor (new Color (pix));
                bg.fillOval (i, j, 10, 10);
            }
        }

灰度(Grayscale)

灰度滤镜(Grayscale Filter)是一种常见的图像处理技术,用于将彩色图像转换为灰度图像。在计算机图像处理中,图像由一个个像素点组成,每个像素点由RGB(红绿蓝)三个颜色通道的值来表示。灰度滤镜的作用就是将每个像素点的RGB值转换为一个灰度值,从而得到灰度图像。

这里仅以for循环语句来讲解实现灰度的逻辑。

for(int i = 0;i<imgArr.length;i++){
  for(int j = 0; j < imgArr[i].length; j++){
  int pixel = imgArr[i][j];
  // 拆分像素 为 RGB
  int red = (pixel >> 16) & 0xFF;
  int green = (pixel >> 8) & 0xFF;
  int blue = pixel & 0xFF;
  // 灰度 gray red = green=blue
  int gray = (red + green + blue) / 3;
  Color color = new Color (gray, gray, gray);
  g.setColor (color);
  g.fillRect (i + 100, j + 100, 1, 1);
  }
}
  • 采用嵌套循环,第一个for遍历imgArr数组的行数,第二个for遍历了每个行的每个元素,也即最终遍历了二维数组的列数。
  • 拆分成RGB三元素,对这三个八位二进制数进行移位操作

总结

       本文以java编程语言编写了几种实现图片滤镜的效果,了解了图像信息在计算机内部是以怎样的形式存在的,对于图片的像素点的处理。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值