项目开发步骤
1 界面开发 美颜相机界面构成: 标题 尺寸 关闭方式 位置 可视化
2 创建主函数调用界面方法
3 添加两个面板 一个是按钮面板一个是图片面板 用JPanel
4 添加按钮到按钮面吧【注意:此时要用初始化按钮面板的方法initBtnPanel 并且将按钮添加到按钮面板上面 要将按钮面板传到方法中】
- 用一维字符串数组表示按钮 然后通过for循环遍历 将按钮文本添加到按钮上面 可以获得按钮的背景颜色 最后按钮一定要添加到按钮面板上
5 添加监听器 动作监听器和按钮监听器 在按钮动作监听器用 e.get~的方法获取文本信息 给按钮也添加监听器 在添加前先创建对象
6 按钮功能的实现 用if 和equals
- 打开功能的实现
先获取图片的绝对路径 用loadImage方法 先读取文件后ImageIO.read(path)读取文件的像素点 定义一个二维数组来储存图片 后用for遍历图片的像素点 用image.getRGB(i,j) 将BufferedImage对象Image中指定位置(i,j)的像素颜色取出来储存到二维数组中 for循环结束后 可输出图片加载完成
用文件选择器打开文件 FileChosser 打开文件位置null 用if判断选择时点了确定按钮 后获取所选择的文件的绝对路径 然后对图像处理对象 调用加载图像的方法将 转为像素的二维数组
- 原图功能的实现
画图片drawImage 现将像素取出来 然后获取每个像素点的颜色 将颜色给画笔【画笔是从绘制面板传过来】 后绘制像素点
在ImageProUI类中获取显示图片画板的画笔 然后imageLister对象中ImageUtils对象的画笔是面板的画笔【将面板的画笔赋给它】
后在按钮功能实现的地方调用方法
package lfx250220;
import javax.swing.*;
import java.awt.*;
import java.awt.image.ImageObserver;
import java.text.AttributedCharacterIterator;
public class ImageProUI {
//界面开发 先写一个个方法然后把界面创建出来
//创建面板 JPanle
//创建一个监听器
ImageLister imageLister=new ImageLister();
public void showUI(){
JFrame jf= new JFrame();
//界面:大小 位置 关闭方式 可视化 布局方式
jf.setTitle("美颜相机");
jf.setSize(900,900);
jf.setLocationRelativeTo(null);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//JPanel类 面板 相当于一个容器
JPanel btnPanel = new JPanel();
JPanel imgPanel = new JPanel();
//设置面板属性
btnPanel.setBackground(Color.CYAN);
imgPanel.setBackground(Color.BLUE);
//设置宽高用到Dimension类 维度
Dimension dimension = new Dimension(300,100);
btnPanel.setPreferredSize(dimension);
//初始化按钮面板 调用initBtnPanel这个方法
initBtnPanel(btnPanel);
//布局: 流式布局(JPanel 默认布局) 边框布局(窗体的默认布局)
//将面板添加到窗体上 用BorderLayout布局
//BorderLayout布局: 是JFrame 的默认布局管理器 将容器划分为五个区域
//北(BorderLayout.NORTH) 南(BorderLayout.SOUTH) 东(BorderLayout.EAST) 西(BorderLayout.WEST) 中(BorderLayout.CENTER)
jf.add(btnPanel,BorderLayout.NORTH);
jf.add(imgPanel,BorderLayout.CENTER);
//FlowLayout flowLayout = new FlowLayout();
//BorderLayout borderLayout = new BorderLayout();
//jf.setLayout(flowLayout);
//jf.setLayout(borderLayout);
jf.setVisible(true);
//获取 显示图片的画板 的画笔
Graphics gra=imgPanel.getGraphics();
imageLister.imageUtils.gra=gra;
//gra是imageLister对象中imageUtils对象中的画笔
}
//初始化按钮面板
//按钮是要添加到按钮面板上 所以要把按钮面板传过来
public void initBtnPanel(JPanel btnPanel){
String[] btnTexts = {"打开","保存","原图","马赛克","灰度"};
//遍历 将每个按钮写出来 然后设置颜色
for (int i=0;i< btnTexts.length;i++){
JButton btn=new JButton(btnTexts[i]);
btn.setBackground(Color.ORANGE);
btnPanel.add(btn);
btn.addActionListener(imageLister);
}
String[] btnTexts2={"画笔","直线","矩形","填充","截图","马赛克画笔"};
for (int i=0;i< btnTexts2.length;i++){
JButton btn=new JButton(btnTexts2[i]);
btn.setBackground(Color.GREEN);
btnPanel.add(btn);
btn.addActionListener(imageLister);
}
}
public static void main(String[] args) {
ImageProUI showui=new ImageProUI();
showui.showUI();
}
}
package lfx250220;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class ImageLister implements MouseListener, ActionListener {
//【注意:函数的调用需要用对象来实现】
//图像处理器
ImageUtils imageUtils=new ImageUtils();
@Override
public void actionPerformed(ActionEvent e) {
//按钮的动作监听器 获取按钮的文本
String ac=e.getActionCommand();
System.out.println("ac"+ac);
//按钮功能的实现
if (ac.equals("打开")){
//打开图片 目的 获取一张照片的绝对路径
//用文件选择器将图片打开
//文件过滤器
FileNameExtensionFilter filter = new FileNameExtensionFilter
("JPG & PNG","jpg", "png");
//文件选择器
JFileChooser jfc = new JFileChooser();
int state = jfc.showOpenDialog(null);//参数对他的作用是一个位置作用 写成空就是居中
if (state==JFileChooser.APPROVE_OPTION){//选择时点了确定按钮
//获取所 选择的文件的 绝对路径
String path = jfc.getSelectedFile().getAbsolutePath();
//图像处理对象 调用加载图片的方法 转为像素的二维数组
imageUtils.loadImage(path);
}
} else if (ac.equals("保存")) {
}else if (ac.equals("原图")) {
imageUtils.drawImage();
}else if (ac.equals("马赛克")) {
}else if (ac.equals("灰度化")) {
}
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
package lfx250220;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class ImageUtils {
//定义一个属性 储存图片的二维数组
static int[][] imgArr;
//宽度和高度
int w;
int h;
Graphics gra = null;//从绘制面板上将画笔传过来
//加载图片
public static void loadImage(String path){
File file = new File(path);
//读取文件的内容
//补充:
//BufferedImage 可理解为一个包含图像像素数据的缓冲区 不仅储存了图像的像素信息 还包含了图像的颜色模型 透明度等属性
//也可以把他看成一个二维的像素数组 每个像素都有对应的颜色值
//主要作用:
//图像读取与储存 处理图像文件一般把BufferedImage当做中间对象 在该项目代码就是这个作用
//图像编辑与处理 BufferedImage提供丰富的方法来操作图像的像素 通过修改BufferedImage的像素值 可以是实现各种图像特效
//图像显示 Java中 可以将BufferedImage对象绘制到Graohics上下文上 从而在窗口中显示图像
//ImageIO.read(file)方法尝试从文件File中读取图像 是Java标准库中用于读取图像文件的静态方法
try {
BufferedImage image=ImageIO.read(file);
//获取图片的宽度和高度
int w=image.getWidth();
int h= image.getHeight();
//创建一个空的数组 储存图片的像素值
imgArr = new int[w][h];
//将图片的像素值复制到数组中
for (int i=0;i<w;i++){
for (int j=0;j<h;j++){
imgArr[i][j]=image.getRGB(i,j);//将BufferedImage对象Image中指定位置(i,j)的像素颜色取出来 并储存在二维数组
}
}
System.out.println("加载图片完成");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
//绘制图像的方法
public void drawImage(){
//先将像素取出来
for (int i=0;i<w;i++){
for (int j=0;j<h;j++){
int pixNum = imgArr[i][j];
Color color= new Color(pixNum);
gra.setColor(color);
gra.fillRect(i,j,1,1);//绘制像素点
}
}
}
}
补充内容:复盘遇到的问题以及文件选择器和获取图片路径的方法
- 复盘遇到的问题
- 1 用for循环遍历数组的时候 从i= 0 即数组的第一个数开始 并且 i = 数组的长度 这会引起索引越界的问题
- 2 把按钮添加到面板上用的方法是初始化按钮面板 initBtnPanel
- 文件选择器
- JFileChooser 的使用方法
- 1创建JFileChooser 对象
- 2显示文件选择器的对话框
- 3 处理用户的选择结果 用if
package lfx250223;
import javax.swing.*;
public class JFileChooserExample {
public static void main(String[] args) {
//使用步骤
// 1 创建JFileChooser对象
JFileChooser jFileChooser = new JFileChooser();
// 2 显示文件选择器对话框 位置null
int state = jFileChooser.showOpenDialog(null);
// 3 处理用户的选择结果
if (state==JFileChooser.APPROVE_OPTION){
//用户点击了 打开 按钮
java.io.File selectedFile = jFileChooser.getSelectedFile();
//getSelectedFile() 是JFileCHooser类的一个方法
//作用是获取用户在文件选择对话框中选定的文件 该方法会返回一个java.io.File 类的对象 该对象表示用户所选择的文件
//java.io.File selectedFile:声明了一个 java.io.File 类型的变量 selectedFile,并把 getSelectedFile() 方法返回的文件对象赋值给它。
JOptionPane.showMessageDialog(null,"你选择的文件是:"+selectedFile.getAbsolutePath());
//JOptionPane:这是 Java Swing 库中的一个类,可用于创建各种对话框,像消息对话框、确认对话框等。
//showMessageDialog:这是 JOptionPane 类的一个静态方法,用于显示一个消息对话框。
//第一个参数 null:表示对话框的父组件,这里传入 null 意味着对话框会显示在屏幕中央。
//第二个参数:是要显示的消息内容。selectedFile.getAbsolutePath() 方法会返回所选文件的绝对路径,把这个路径和提示信息拼接后作为消息内容显示在对话框里。
}
else if (state == JFileChooser.CANCEL_OPTION) {
// 用户点击了“取消”按钮
JOptionPane.showMessageDialog(null, "你取消了文件选择。");
}
}
}
- 获取图片路径
在inageUtils中定义一个二维数组 然后用loadImage方法【(String path)】 定义对象File 然后for遍历得到文件中图片的像素点 并且储存到二维数组中 此时用到的是image.getRGB(i,j)
【详细代码看上边】