图像浏览器的设计与实现
- 前言
- 一、需求分析
- 选题意义
- 应用意义
- 功能需求
- 关键技术
- 系统用例图设计
- JPG系统用例图
- 图片查看系统用例图
- 二、概要设计
- JPG.java
- Picture.java
- 三、详细设计
- 类图
- JPG.java UML类图
- picture.java UML类图
- 界面设计
- JPG.java
- picture.java
- 四、源代码
- JPG.java
- picture.java
前言
推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏网站,请点击下方链接查看。
https://www.captainbed.cn/f1
本文概述了图像浏览器的设计思路与实现过程,涉及界面布局、功能需求、交互逻辑、图像处理技术等方面的内容。设计旨在提供用户友好的界面,支持图像浏览、缩放、旋转等基本操作。实现过程包括前端界面开发、后端数据处理以及必要的性能优化措施,确保图像浏览器的高效稳定运行。
一、需求分析
图形浏览器的设计与实现是一个涵盖多个功能需求的项目,主要旨在提供用户友好的界面来浏览、管理和操作图片集合。通过Java语言实现图形浏览器的设计与实现算法,可以帮助我们更好地理解和解决实际问题。
选题意义
通过直观的界面和多功能操作,提高用户浏览、管理和操作图片集合的效率和满意度。良好的用户体验能够吸引更多用户使用并持续使用该软件。
应用意义
- 教育与研究应用:在教育领域,图像浏览器可以作为一个便捷的工具,帮助教和学生展示、分析和讨论图像数据。在研究中,研究人员可以利用图像浏览器进行实验数据的可视化和比较分析,加深对数据的理解。
- 商业应用:在商业环境中,图像浏览器可以用于产品展示、设计审查和市场分析。例如,设计师可以使用它来查看和调整产品设计图像;市场分析师可以使用它来快速浏览和比较市场竞品的图片信息。
- 技术挑战与创新:图像浏览器的设计与实现涉及到诸如图像处理、用户界面设计、数据结构和算法优化等多个技术领域的挑战。解决这些挑战不仅可以提高软件的性能和稳定性,还能促进技术创新和进步。
功能需求
- 功能一:我们可以在程序上进行随意绘画,点击保存按钮,我们可以将刚才绘画的内容进行保存,可以选择自己所需要的类型进行保存
- 功能二:在界面上按照提示,点击“浏览”按钮,打开文件对话框,选择图片,图片会显示在页面中,并可以通过点击“上一个”“下一个”按钮实现图片的上下翻看,点击“删除”按钮,则将当前图片删除。界面一目了然,很容易看懂。若选择的图片类型不是jpg或png格式,或直接点击“上一张”“下一张”“删除”按钮,则出现警告对话框,提示相关信息。在打开图片后,点击“删除”按钮,则出现确定对话框,询问相关信息。
关键技术
在总体设计过程中涉及了多种技术,其中关键技术包括两个方面:浏览图片和删除图片。
- 浏览图片主要完成在本地磁盘里选取并打开图片,实现在页面中显示选择图片效果;
- 删除图片主要完成对图片的删除,实现页面上显示的图片的删除效果;
系统用例图设计
JPG系统用例图

图片查看系统用例图

二、概要设计
JPG.java
class PaintCanvas extends Canvas类, 这个代码实现了一个绘图Canvas组件,用户可以在Canvas上用鼠标拖动绘制线条,并且绘图的内容会保存在drawingArea中供进一步使用。PaintCanvas类继承自 Canvas 类,提供了一个可以绘图的画布- 该类有以下成员变量:
pathPoints: 一个List<Point2D>类型的变量,用于存储鼠标拖动时的路径点。drawingArea: 一个BufferedImage类型的变量,用于存储绘图区域的内容。g2D: 一个Graphics2D类型的变量,用于在drawingArea上进行绘图操作。
- 在构造函数中:
- 创建了一个 300x300 像素的
BufferedImage作为绘图区域,并获取它的Graphics2D对象。 - 添加了鼠标拖动事件监听器,在鼠标拖动时将鼠标位置记录到
pathPoints列表中,并使用临时的Graphics2D对象绘制路径。 - 添加了鼠标释放事件监听器,在鼠标释放时清空
pathPoints列表。
- 创建了一个 300x300 像素的
- 该类有以下成员变量:
private void drawPath(Graphics2D g2D)方法用于遍历pathPoints列表,并使用Graphics2D对象在drawingArea上绘制连接这些点的直线。public void paint(Graphics g)方法被重写,用于在Canvas组件上绘制drawingArea的内容。public void update(Graphics g)方法也被重写,直接调用paint()方法。public BufferedImage getDrawingArea()方法返回drawingArea变量,以便外部获取绘图区域的内容。WindowCanvas类实现了一个简单的绘图应用程序,可以创建了一个包含绘图面板和保存按钮的窗口应用程序,允许用户绘制图形并将绘制结果保存为PNG图像文件。继承自JFrame,表示整个窗口。实现了ActionListener接口,用于监听按钮点击事件。- 成员变量:
PaintCanvas canvas: 一个PaintCanvas对象,即绘图面板,用户可以在这个面板上绘图。JButton button: 一个按钮,标签为 “保存”,用于触发保存操作。
- 构造函数:
- 初始化按钮,并为按钮添加点击事件监听器。
- 设置窗口布局为
BorderLayout,并将绘图面板canvas放置在窗口中央,按钮放置在窗口底部。
actionPerformed方法:当用户点击按钮时触发此方法。首先检查事件源是否为 “保存” 按钮。如果是,调用canvas.getDrawingArea()获取绘图面板的图像BufferedImage。创建一个文件选择器JFileChooser,设置默认文件名和文件类型过滤器(这里是PNG格式)。弹出文件保存对话框,让用户选择保存的位置和文件名。如果用户确认保存操作,将图像以PNG格式写入用户选择的文件中。
- 成员变量:
- PG类,用于启动绘图程序
Picture.java
class PictureEdit extends JFrame implements ActionListener,FilenameFilter类通过继承父类JFrame,和接口ActionListener,FilenameFilter实现对绘制的图片进行查看,或者对已有的图片进行旋转、放大、缩小、下一张、上一张和删除- 成员变量:
- 在查看图片的时候控制数组的下标
- 在对图片进行处理的时候控制数组的下标
str判断读取文件的后缀名是jpg还是pngFileDialog open文件对话框JButton before,next,skim,delete,rotate,zoomIn,zoomOut按钮JPanel p1容器Jlabel label标签Icon icon1小图像接口
- 构造方法:这个构方法是
PictureEdit类的一部分,该类是一个自定义的图形用户界面(GUI)窗口,用于浏览和编辑图片。它继承自JFrame,并实现了ActionListener接口,这意味着它可以响应按钮点击等事件。
- 成员变量:
public boolean accept(File dir, String name)主要用于确定给定的文件名(name)是否以指定的后缀(在这里是.jpg或.png)结尾。private BufferedImage loadImage(String path)该方法用于从给定的文件路径path加载一个图像,并返回一个BufferedImage对象。private BufferedImage rotateImage(BufferedImage image)该方法接受一个BufferedImage对象作为参数,并返回旋转了90度的同类型新BufferedImage对象。private BufferedImage scaleImage(BufferedImage image, double scaleFactor),该方法接受一个BufferedImage对象和一个double类型的缩放因子scaleFactor,并返回一个新的缩放后的BufferedImage对象。public void actionPerformed(ActionEvent e)点击按钮之后涉及的触发事件装置,会对图片进行浏览,删除,放大,缩小,旋转,下一张,上一张的操作public class picture用于启动图像浏览器
三、详细设计
类图
JPG.java UML类图

picture.java UML类图

界面设计
JPG.java

picture.java

四、源代码
JPG.java
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.filechooser.FileNameExtensionFilter;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
class PaintCanvas extends Canvas {
private final List<Point2D> pathPoints = new ArrayList<>();
private final BufferedImage drawingArea;
private final Graphics2D g2D;
public PaintCanvas() {
int width = 300;
int height = 300;
drawingArea = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); // 透明背景
g2D = drawingArea.createGraphics();
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
pathPoints.add(new Point2D.Double(e.getX(), e.getY()));
if (pathPoints.size() > 1) {
Graphics2D tempG2D = drawingArea.createGraphics();
drawPath(tempG2D);
tempG2D.dispose();
}
repaint();
}
});
addMouseListener(new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
pathPoints.clear();
}
});
}
private void drawPath(Graphics2D g2D) {
g2D.setPaint(Color.BLACK); // 或者根据需要设置绘制颜色
for (int i = 0; i < pathPoints.size() - 1; i++) {
Point2D p1 = pathPoints.get(i);
Point2D p2 = pathPoints.get(i + 1);
g2D.drawLine((int) p1.getX(), (int) p1.getY(), (int) p2.getX(), (int) p2.getY());
}
}
@Override
public void paint(Graphics g) {
g.drawImage(drawingArea, 0, 0, this);
}
@Override
public void update(Graphics g) {
paint(g);
}
public BufferedImage getDrawingArea() {
return drawingArea;
}
}
class WindowCanvas extends JFrame implements ActionListener {
PaintCanvas canvas = new PaintCanvas();
JButton button = new JButton("保存");
WindowCanvas(String s) {
super(s);
// 添加按钮并设置监听器
button.addActionListener(this);
// 设置布局并添加组件
getContentPane().add(canvas, BorderLayout.CENTER);
getContentPane().add(button, BorderLayout.PAGE_END); // 底部,相当于BorderLayout.SOUTH
// 设置窗口属性
setBounds(100, 100, 400, 400);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
// 检查事件源是否为"保存"按钮
if (e.getSource() == button) {
// 获取绘图面板的图像
BufferedImage image = canvas.getDrawingArea();
// 保存图像到文件
try {
// 创建文件选择器
JFileChooser fileChooser = new JFileChooser();
// 设置文件选择器默认文件名和目录
fileChooser.setSelectedFile(new File("A.png"));
// 添加文件过滤器,允许用户选择保存的文件类型
FileNameExtensionFilter filter = new FileNameExtensionFilter("PNG Images", "png");
fileChooser.setFileFilter(filter);
// 显示保存对话框
int result = fileChooser.showSaveDialog(null);
// 如果用户选择了保存
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
String filePath = selectedFile.getAbsolutePath();
// 确保文件扩展名为.png
if (!filePath.toLowerCase().endsWith(".png")) {
filePath += ".png";
}
// 保存图像到文件
ImageIO.write(image, "png", new File(filePath));
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
public class JPG {
public static void main(String[] args) {
// 创建并显示窗口
SwingUtilities.invokeLater(() -> {
WindowCanvas wc = new WindowCanvas("画图软件");
});
}
}
picture.java
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
class PictureEdit extends JFrame implements ActionListener, FilenameFilter {
int j = 0;
int b;
boolean str = false;
final FileDialog open;
final JButton before;
final JButton next;
final JButton skim;
final JButton delete;
final JPanel p1;
final JLabel label;
Icon icon1;
final JButton rotate = new JButton("旋转");
final JButton zoomIn = new JButton("放大");
final JButton zoomOut = new JButton("缩小");
PictureEdit() {
super("图像浏览器");
before = new JButton("上一张");
next = new JButton("下一张");
skim = new JButton("浏 览");
delete = new JButton("删 除");
p1 = new JPanel();
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);//设置标签中内容的水平对齐方式
before.setFont(new Font("Dialog", Font.PLAIN, 20));
next.setFont(new Font("Dialog", Font.PLAIN, 20));
skim.setFont(new Font("Dialog", Font.PLAIN, 20));
delete.setFont(new Font("Dialog", Font.PLAIN, 20));
label.setFont(new Font("Dialog", Font.BOLD, 60));
rotate.setFont(new Font("Dialog", Font.PLAIN, 20));
zoomIn.setFont(new Font("Dialog", Font.PLAIN, 20));
zoomOut.setFont(new Font("Dialog", Font.PLAIN, 20));
label.setText("请点击浏览选择图片");
label.setForeground(Color.red);
open = new FileDialog(this, "打开文件对话框", FileDialog.LOAD);
open.setVisible(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p1.add(rotate);
p1.add(zoomIn);
p1.add(zoomOut);
p1.add(before);
p1.add(next);
p1.add(skim);
p1.add(delete);
add(p1, BorderLayout.SOUTH);
add(label, BorderLayout.CENTER);
skim.addActionListener(this);//按钮的注册监听
delete.addActionListener(this);
before.addActionListener(this);
next.addActionListener(this);
rotate.addActionListener(this);
zoomIn.addActionListener(this);
zoomOut.addActionListener(this);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}
);//窗口适配器
open.setFilenameFilter(this);
open.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
open.setVisible(false);
}
}
);//对话框适配器
setBounds(200, 100, 800, 600);
setVisible(true);
validate();
}
public boolean accept(File dir, String name) {
String s = ".jpg";
String s2 = ".png";
return name.endsWith(s) || name.endsWith(s2);
}
private BufferedImage loadImage(String path) {
try {
return ImageIO.read(new File(path));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private BufferedImage rotateImage(BufferedImage image) {
int width = image.getWidth();
int height = image.getHeight();
BufferedImage rotatedImage = new BufferedImage(width, height, image.getType());
Graphics2D g2d = rotatedImage.createGraphics();
AffineTransform transform = new AffineTransform();
transform.rotate(Math.toRadians(90), (double) width / 2, (double) height / 2);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(image, transform, null);
g2d.dispose();
return rotatedImage;
}
private BufferedImage scaleImage(BufferedImage image, double scaleFactor) {
int width = (int) (image.getWidth() * scaleFactor);
int height = (int) (image.getHeight() * scaleFactor);
// Create a new BufferedImage with transparency support
BufferedImage scaledImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
// Get the graphics context of the new image
Graphics2D g2d = scaledImage.createGraphics();
// Set rendering hints to improve the quality
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Scale the original image to the new image
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return scaledImage;
}
public void actionPerformed(ActionEvent e) {
int i = 0;
BufferedImage currentImage = null;
if (e.getSource() == skim) {
str = true;
open.setVisible(true);
String str = open.getFile();
while (!str.endsWith(".jpg") && !str.endsWith(".png")) {
JOptionPane.showMessageDialog(this, "请选择jpg或png格式的图片!", "警告对话框", JOptionPane.WARNING_MESSAGE);
open.setVisible(true);
str = open.getFile();
}
label.setText("");
icon1 = new ImageIcon(open.getDirectory() + open.getFile());
label.setIcon(icon1);
} else {
if (!str) {
JOptionPane.showMessageDialog(this, "请点击浏览以选择图片!", "警告对话框", JOptionPane.WARNING_MESSAGE);
} else {
File dir = new File(open.getDirectory());
String[] fileName = dir.list(this);
if (fileName != null) {
for (i = 0; i < fileName.length; i++) {
if (fileName[i].equals(open.getFile()))
break;
}
}
if (e.getSource() == before) {
if (j == -i) if (fileName != null) {
j = fileName.length - i;
}
b = i + (--j);
if (fileName != null) {
icon1 = new ImageIcon(open.getDirectory() + fileName[b]);
}
label.setIcon(icon1);
label.setText("");
}
if (e.getSource() == next) {
if (fileName != null && j == fileName.length - i - 1) j = -i - 1;
b = i + (++j);
label.setText("");
if (fileName != null) {
icon1 = new ImageIcon(open.getDirectory() + fileName[b]);
}
label.setIcon(icon1);
}
if (e.getSource() == delete) {
int n = 0;
if (fileName != null) {
n = JOptionPane.showConfirmDialog(this, "确定要删除" + fileName[b] + "图像文件吗?", "确定文件夹删除", JOptionPane.YES_NO_CANCEL_OPTION);
}
if (n == JOptionPane.YES_OPTION) {
File f = null;
if (fileName != null) {
f = new File(open.getDirectory() + fileName[b]);
}
if (f != null) {
f.delete();
}
if (fileName != null) {
icon1 = new ImageIcon(open.getDirectory() + fileName[b + 1]);
}
label.setIcon(icon1);
}
}
if (e.getSource() == rotate) {
// if (fileName != null && j == fileName.length - i - 1) j = -i - 1;
// b = i + (++j);
//label.setText("");
if (fileName != null) {
currentImage= loadImage(open.getDirectory() + fileName[b]) ;
}
if (currentImage != null) {
currentImage = rotateImage(currentImage);
label.setIcon(new ImageIcon(currentImage));
}
}
if (e.getSource() == zoomIn) {// 放大1.5倍
// if (fileName != null && j == fileName.length - i - 1) j = -i - 1;
// b = i + (++j);
//label.setText("");
if (fileName != null) {
currentImage= loadImage(open.getDirectory() + fileName[b]) ;
}
if (currentImage != null) {
currentImage = scaleImage(currentImage, 1.5);
label.setIcon(new ImageIcon(currentImage));
}
}
if (e.getSource() == zoomOut) {
//if (fileName != null && j == fileName.length - i - 1) j = -i - 1;
//b = i + (++j);
//label.setText("");
if (fileName != null) {
currentImage= loadImage(open.getDirectory() + fileName[b]) ;
}
if (currentImage != null) {
currentImage = scaleImage(currentImage, 0.5);
label.setIcon(new ImageIcon(currentImage));
}
}
}
}
}
}
public class picture {
public static void main(String[] args) {
new PictureEdit();
}
}















![SpringBoot学习06-[SpringBoot与AOP、SpringBoot自定义starter]](https://img-blog.csdnimg.cn/direct/2bb9a6af1b574a31aeef3b766cae26f5.png)


