任务:
Java实验任务:
设计一个 JFrame 窗体,窗体中的菜单 栏里面有两个菜单,分别是“文件”和“图像处理”。现在要求在文件菜单下添加一个子菜单元素“打开图片”。点击“打开图片”之后,弹出文件选择界面,选择电脑上任意一张图片,在 JFrame 窗体上能正常显示;“图像处理”菜单下要求添加一个子菜单元素:“均衡化图片”。点击“均衡化图片之后”,能把所显示的图片进行均衡化处理后重新显示。
老样子,先来最终的实现效果
ps:我发现均衡化处理图片的效果好像是把暗一点的图片转为明亮一点的图片,然后会把亮一点的图片转化为暗一点的图片😂(不确定是不是这样,但是我传了一张亮一点和暗一点的图片好像肉眼看到的效果是这样
设计思路:
- 创建图形界面(GUI):使用Java Swing库创建一个窗口(JFrame),在窗口中添加一个标签(JLabel),用于显示处理后的图片。
- 读取图片:使用ImageIO类的read方法读取指定路径的图片文件,获取原始图片的像素矩阵。
- 图像均衡化处理:通过balance方法对原始图片的像素矩阵进行均衡化处理。该方法首先计算原始图片的灰度直方图,然后根据直方图计算累积概率分布,最后根据累积概率分布对原始像素进行映射,得到均衡化后的像素矩阵。
- 将处理后的像素矩阵转换为图片:使用createImage方法将处理后的像素矩阵转换为Image对象,然后通过toBufferedImage方法将Image对象转换为BufferedImage对象。
- 显示处理后的图片:将处理后的BufferedImage对象设置为标签(JLabel)的图标,并将标签添加到窗口(JFrame)中,最后设置窗口可见并调整窗口大小以适应图片大小。
具体实现代码:
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.awt.image.PixelGrabber;
import java.io.File;
import java.io.IOException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class shiyan3 extends JFrame {
private JLabel imageLabel;
public shiyan3() {
setTitle("图像处理");
setSize(800, 600);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("文件");
JMenuItem openImageMenuItem = new JMenuItem("打开图片");
openImageMenuItem.addActionListener(new OpenImageListener());
fileMenu.add(openImageMenuItem);
JMenu imageProcessingMenu = new JMenu("图像处理");
JMenuItem equalizeImageMenuItem = new JMenuItem("均衡化图片");
equalizeImageMenuItem.addActionListener(new EqualizeImageListener());
imageProcessingMenu.add(equalizeImageMenuItem);
menuBar.add(fileMenu);
menuBar.add(imageProcessingMenu);
setJMenuBar(menuBar);
imageLabel = new JLabel();
add(imageLabel, BorderLayout.CENTER);
setVisible(true);
}
private class EqualizeImageListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
if (imageLabel.getIcon() != null) {
ImageIcon icon = (ImageIcon) imageLabel.getIcon();
Image image = icon.getImage();
BufferedImage bufferedImage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = bufferedImage.createGraphics();
g2d.drawImage(image, 0, 0, null);
g2d.dispose();
int[] currentPixArray = getPixArray(bufferedImage);
int[] resultArray = balance(currentPixArray, bufferedImage.getWidth(), bufferedImage.getHeight());
Image newImage = createImage(new MemoryImageSource(bufferedImage.getWidth(), bufferedImage.getHeight(), resultArray, 0, bufferedImage.getWidth()));
BufferedImage equalizedImage = toBufferedImage(newImage);
ImageIcon newIcon = new ImageIcon(equalizedImage);
imageLabel.setIcon(newIcon);
} else {
JOptionPane.showMessageDialog(null, "请先打开一张图片", "提示", JOptionPane.INFORMATION_MESSAGE);
}
}
}
private class OpenImageListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
JFileChooser fileChooser = new JFileChooser();
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
try {
BufferedImage image = ImageIO.read(selectedFile);
ImageIcon icon = new ImageIcon(image);
imageLabel.setIcon(icon);
} catch (IOException ex) {
JOptionPane.showMessageDialog(null, "无法打开图片", "错误", JOptionPane.ERROR_MESSAGE);
}
}
}
}
private int[] getPixArray(BufferedImage image) {
int w = image.getWidth();
int h = image.getHeight();
int[] pix = new int[w * h];
PixelGrabber pg = new PixelGrabber(image, 0, 0, w, h, pix, 0, w);
try {
pg.grabPixels();
} catch (InterruptedException e) {
e.printStackTrace();
}
return pix;
}
private int[] balance(int[] srcPixArray, int w, int h) {
int[] histogram = new int[256];
int[] dinPixArray = new int[w * h];
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int grey = srcPixArray[i * w + j] & 0xff;
histogram[grey]++;
}
}
double a = (double) 255 / (w * h);
double[] c = new double[256];
c[0] = (a * histogram[0]);
for (int i = 1; i < 256; i++) {
c[i] = c[i - 1] + (int) (a * histogram[i]);
}
for (int i = 0; i < h; i++) {
for (int j = 0; j < w; j++) {
int grey = srcPixArray[i * w + j] & 0x0000ff;
int hist = (int) c[grey];
dinPixArray[i * w + j] = 255 << 24 | hist << 16 | hist << 8 | hist;
}
}
return dinPixArray;
}
private Image createImage(MemoryImageSource source) {
return Toolkit.getDefaultToolkit().createImage(source);
}
private BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
BufferedImage bimage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bimage.createGraphics();
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
new shiyan3();
});
}
}
保姆级展示点击操作
-
运行程序
-
点击文件里的打开图片按钮
-
选择一张图片上传
-
点击图像处理进行图像均衡化处理后的图片如上所示
-
完结撒花 ★,°:.☆( ̄▽ ̄)/$:.°★ 🎇 。