图像原理
图片是一种可视化的信息表示方式,它是由像素(或图像元素)组成的二维网格。每个像素都代表图像的一小部分,其颜色和亮度值决定了该部分的外观。图片原理涉及以下关键概念:
-
像素(Pixel):像素是图像的最小单元。它是一个小的方块或点,通常由一个或多个颜色通道的数值来描述。颜色通道可以是红色、绿色、蓝色(RGB)或其他颜色模型中的成分。
-
分辨率(Resolution):分辨率指的是图像的大小,通常以像素为单位来表示。高分辨率图像包含更多的像素,因此能够呈现更多的细节。低分辨率图像则包含较少的像素,因此会失去一些细节。
-
颜色深度(Color Depth):颜色深度表示每个像素可以表示的不同颜色数量。通常以位(bit)来度量,例如 8 位颜色深度允许每个像素表示 256 种不同的颜色。颜色深度越高,图像的颜色精度越高。
-
色彩模型(Color Model):色彩模型定义了图像中颜色的表示方式。常见的色彩模型包括 RGB(红绿蓝)、CMYK(青、品红、黄、黑)和灰度(黑白)等。不同的色彩模型用于不同的应用,例如 RGB 用于屏幕显示,CMYK 用于印刷。
像素点是数字图像的基本构建块,它们包含了图像的信息,通过组合和处理像素,我们可以创建、编辑和显示各种类型的图像。
接下来尝试用代码来绘制一张像素图
package PicFilter.Lyjm0926.imagepro;
import javax.swing.*;
import java.awt.*;
import java.util.Random;
public class ImageProUI extends JFrame {
public void showUI(){
setTitle("图像像素原理");
setSize(800,600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
//EXIT_ON_CLOSE(在 JFrame 中定义):使用 System exit 方法退出应用程序。仅在应用程序中使用。
//默认情况下,该值被设置为 HIDE_ON_CLOSE
setVisible(true);//设置窗体可见
}
public void paint(Graphics g){
super.paint(g);
Random random = new Random();
int w= 300,h=300;
int[][]pixArr = new int[w][h];
for(int i =0 ;i < 300;i++){
for(int j = 0; j < 300;j++){
int red = random.nextInt(256);
int green = random.nextInt(256);
int blue = random.nextInt(256);
int rgb =(red<<16)+(green<<8)+(blue);
pixArr[i][j] = rgb;}
}
for(int i = 0; i < 300; i++){
for(int j = 0; j < 300; j++){
// 取出像素值
int rgb = pixArr[i][j];
int red = rgb >> 16;
int green = rgb >> 8;
int blue = rgb >> 0;
red = red & 255;
green = green & 255;
blue = blue & 255;
// 创建一个颜色对象 将RGB设置给颜色对象
Color color = new Color (red, green, blue);
g.setColor (color);
g.fillRect (20 + i, 100 + j, 1, 1);
}
}
for(int i = 0; i < 300; i+=10){
for(int j = 0; j < 300; j+=10){
// 取出像素值
int rgb = pixArr[i][j];
int red = rgb >> 16;
int green = rgb >> 8;
int blue = rgb >> 0;
red = red & 255;
green = green & 255;
blue = blue & 255;
// 创建一个颜色对象 将RGB设置给颜色对象
Color color = new Color (red, green, blue);
g.setColor (color);
g.fillOval (350 + i, 100 + j, 10, 10);
}
}
}
public static void main (String[] args){
ImageProUI imageProUI = new ImageProUI();
imageProUI.showUI();
}
}
成功使用随机颜色的像素点构成了一张数字像素图
对图片进行读取并添加滤镜
要点及所使用的主要类和方法
- ImageIO 负责读写图片
- 读: 将一个图片文件对象 读取成一个BufferedImage对象
- 写: 将一个Image对象 保存为一个电脑上的图片文件
package PicFilter.Lyjm1004.imagepro;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageProUI extends JFrame {
public void showUI(){
setTitle("图像滤镜2");
setSize(1500,1500);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);//数据类型boolean
}
@Override
public void paint(Graphics g) {
super.paint(g);
int[][] imgArr = getImagePixs("C:\\Users\\liuyang\\Desktop\\pic2.jpg");
int w = imgArr.length;
int h = imgArr[0].length;
for (int i=0;i<w;i++){
for (int j=0; j<h;j++){
int rgb =imgArr[i][j];
Color color =new Color(rgb);
g.setColor(color);
g.fillRect(100 + i, 80 + j, 1, 1);//fillrect 是Java绘图中的一个基本方法,它用来填充一个矩形区域,
// 即在指定矩形区域内填充所指定的颜色,可实现画图工具类似“填色”的功能。它是 java.awt 包中 Graphics 类的一个重要方法
}
}
/*for (int i=0;i<w;i+=10){
for (int j=0; j<h;j+=10){
int rgb =imgArr[i][j];
Color color =new Color(rgb);
g.setColor(color);
g.fillRect(700 + i, 80 + j, 10, 10);//fillrect 是Java绘图中的一个基本方法,它用来填充一个矩形区域,
// 即在指定矩形区域内填充所指定的颜色,可实现画图工具类似“填色”的功能。它是 java.awt 包中 Graphics 类的一个重要方法
}
}*/
for(int i = 0; i < w; i += 1){
for(int j = 0; j < h; j += 1){
int rgb = imgArr[i][j];
Color color = new Color (rgb);
int red = color.getRed ();
int green = color.getGreen ();
int blue = color.getBlue ();
int yred = red + 30;
if(yred > 255){
yred = 255;
}
int ygreen = green + 30;
if(ygreen > 255){
ygreen = 255;
}
Color color1 = new Color (yred, ygreen, 255 - blue);
g.setColor (color1);
g.fillRect (900 + i, 80 + j, 1, 1);
}
}
}
public int[][] getImagePixs (String imagePath ){
File file = new File(imagePath);
BufferedImage bufferImg = null;
try{
bufferImg= ImageIO.read(file);
} catch (IOException e) {//异常处理机制
throw new RuntimeException(e);
}
int width = bufferImg.getWidth();
int height = bufferImg.getHeight();
int[][] imgArr = new int[width][height];
//将图像中的像素值取出来
for(int i=0;i<width;i++){
for(int j=0; j<height; j++){
imgArr[i][j]=bufferImg.getRGB(i,j);
}
}
return imgArr;
}
public static void main(String[] args){
ImageProUI imageProUI = new ImageProUI ();
imageProUI.showUI ();
}
}
进行反色处理
虽然成功实现了滤镜处理,但只能通过不断编辑代码来更换滤镜效果,效率低,不便捷,这时就可以引入动作监听器这类接口实现交互
使用按键切换滤镜
package PicFilter.Lyjm1008.imagepro;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ImageListener implements ActionListener {
Graphics g;
int[][] imgArr;
int w;
int h;
ImageTools imageTools = new ImageTools();
public void actionPerformed(ActionEvent e){
String ac = e.getActionCommand ();
System.out.println ("点击了:" + ac);
if(ac.equals ("加载图片")){
imgArr = imageTools.getImagePixs
("C:\\Users\\liuyang\\Desktop\\pic3.jpg");
w = imgArr.length;
h = imgArr[0].length;
} else if(ac.equals ("原图")){
imageTools.drawImage01 (g, imgArr);
} else if(ac.equals ("马赛克")){
imageTools.drawImage02 (g, imgArr);
} else if(ac.equals ("圆点马赛克")){
imageTools.drawImage03 (g, imgArr);
} else if(ac.equals ("灰度")){
imageTools.drawImage04 (g, imgArr);
} else if(ac.equals ("二值化")){
imageTools.drawImage05 (g, imgArr);
} else if(ac.equals ("反片")){
imageTools.drawImage06 (g, imgArr);
} else if(ac.equals ("怀旧")){
imageTools.drawImage07 (g, imgArr);
} else if(ac.equals ("油画")){
imageTools.drawImage08 (g, imgArr);
} else if(ac.equals ("轮廓化")){
imageTools.drawImage09 (g, imgArr);
}
}
}