美颜相机1.0

发布于:2025-02-24 ⋅ 阅读:(13) ⋅ 点赞:(0)

项目开发步骤

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)

【详细代码看上边】