IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 图像处理Image Processing(二) -> 正文阅读

[人工智能]图像处理Image Processing(二)

目录

一.界面概览?

二.功能的实现完善与一些技术细节

(1)ListenerImp类

(2)DrawPanel类

(3)解决图像加载缓慢的问题

(4)关于buffimglist

(5)录制功能:

(6)回放功能

(7)撤回与清空功能

三.Thx


一.界面概览?

这次我们用Java来实现图像处理,先给hxdm上成果:

?如图窗体右方(East)面板按钮的所示的功能是我们的图像处理小项目的主要内容。

关于图像处理的具体方法可以参考我的上一篇博客:

图像处理Image Processing(一)

二.功能的实现完善与一些技术细节

(1)ListenerImp类

? 利用ListenerImp类来实现ActionListener等接口(并不需要实现,真正意义上的实现在ImageListener类中进行),然后再由ImageListener类来继承,来实现我们需要的方法;

这样做有如下几个好处:

  • 如果需要实现的监听器过多,类中的方法太多不便于阅读,况且并不是每个方法我们都要实现;
  • 方便进行方法的添加;
  • 增加了代码的可读性,美观就完事
public class ListenerImp implements ActionListener, MouseListener, MouseMotionListener, ChangeListener, KeyListener {

    @Override
    public void actionPerformed(ActionEvent e) {

    }


    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }

    @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) {

    }

    @Override
    public void mouseDragged(MouseEvent e) {

    }

    @Override
    public void mouseMoved(MouseEvent e) {

    }

    @Override
    public void stateChanged(ChangeEvent e) {

    }
}

(2)DrawPanel类

DrawPanel类是用来重写paint方法实现重绘的类;

? ?其中buffimglist是保存每步操作图像的ArrayList<BufferedImage>,需要注意的是指针悬空问题和绘制图像时要取buffimglist中栈顶元素。(为什么是直接drawImage,而不是打印保存有像素点的二维数组,后文会提到);

public class DrawPanel extends JPanel {
    ArrayList<BufferedImage> buffimglist = new ArrayList<>();
    public void setBuffimglist(ArrayList<BufferedImage> buffimglist) {
        this.buffimglist = buffimglist;
    }
    public void paint(Graphics gr) {
        super.paint(gr);
        System.out.println("paint");
        //防止指针悬空
        if(buffimglist==null ){
            return;
        }
        if(buffimglist.size()==0){
            return;
        }
        //绘制最后存储的图像
        gr.drawImage(buffimglist.get(buffimglist.size()-1), 0, 0, null);
     
    }
}

(3)解决图像加载缓慢的问题

? ?尝试了鄙人上一篇博客中的方法的hxdm会发现一个问题:图像在窗体的打印十分缓慢。

? ?这是因为IO与底层GPU速度不匹配造成的,此时我们进行的是一个一个像素的数据传输,导致图片加载缓慢。解决方法:

  1. 将整张图片的像素点存储起来;
  2. 声明一个BufferedImage对象来存储每张图像的像素点,此操作为纯内存操作;
  3. 整体绘制:在窗体上直接绘制BufferedImage(drawImage方法);

用绘制原图的方法来给大家举例,(其他绘制方法同理):‘

     //绘制原图
     public BufferedImage drawImage(int[][] imgArr) {
        //声明一个空的BufferedImage
        BufferedImage buffimg = new BufferedImage(imgArr.length, imgArr[0].length, BufferedImage.TYPE_INT_ARGB);
        //绘制过程与屏幕刷新无关,纯内存操作
         Graphics bfg = buffimg.getGraphics();
        for(int i = 0; i < imgArr.length; i++) {
            for(int j = 0; j < imgArr[0].length; j++) {
                int rgb = imgArr[i][j];
                Color color = new Color(rgb);
               
                //方法一:把像素保存在缓冲区中
//                buffimg.setRGB(i, j, rgb);
                //方法二:先在内存中绘制
                bfg.setColor(color);
                bfg.fillRect(i,j,1,1);

            }
        }
         //窗体上绘制
         //因为imageListener中调用了repaint,按下按钮后会绘制,所以这里不需要绘制
//        gr.drawImage(buffimg, 0, 0, null);
        return buffimg;
     }
  • 我们并不需要在 drawImage方法中实现窗体绘制的功能,因为我们在imageListener中调用了repaint方法,按下按钮后会绘制,所以这里不需要绘制。这里的绘制方法都只需要存储图像在buffimg中。
  • 修改后的返回值类型为为BufferedImage,原因如下:
  if(str.equals("原图")) {
      buffimg = imageUtils.drawImage(imgArr);
      //加入队列
      buffimglist.add(buffimg);
  }

这样我们可以将每次存储在内存中的图像加入buffimglist中,便于我们的重绘、录制、回放、清空功能的实现。

(4)关于buffimglist

buffimglist的作用是保存我们每一步操作产生的图像,便于我们的重绘、录制、回放、清空功能的实现。

 ArrayList<BufferedImage> buffimglist = new ArrayList<>();

(5)录制功能:

录制功能:因为我们的每步操作都保存在了buffimglist中,所以我们只需要保存录制的起始位置即可还原操作顺序;

 //记录录制的开始与结束位置
    public int start = 0;
    public int end = 0;
    //录制
    public void recordImage() {
        start = this.buffimglist.size() - 1;
        System.out.println("开始录制:" + start);
    }

(6)回放功能

回放功能:有了起始位置,回放就是一个遍历buffimglist的过程;

    //回放
    public void playback() {
        end = this.buffimglist.size();
        for(int i = start; i < end; i++) {
            gr.drawImage(this.buffimglist.get(i), 0, 0, null);
            //相邻图片间隔1s
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

(7)撤回与清空功能

 //撤回
    public void withDraw() {
        if(this.buffimglist.size() > 1) {
            this.buffimglist.remove(this.buffimglist.size()-1);
        } else {
            System.out.println("不能撤回!!");
        }
    }

    //清空
    public void clearScreen() {
        this.buffimglist.clear();
    }

三.Thx

谢谢你这么好看还看完了我的博客!

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-08-24 15:33:09  更:2021-08-24 15:33:31 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 18:45:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码