11月20日

任务三:

阅读百度给出的官方文档可知,需要将照片处理为json数据然后调用api上传,然后需要将api返回的json数据转化为图片形式显示在gui界面上。

Gui设计了两个按钮,一个是上传图片一个是保存图片(图片一经上传就直接被优化返回,不需要网络优化按钮)。软件对照片进行了初步的处理,在保留长宽比的基础上在gui界面上完整的居中显示(包括返回的照片)。点击保存按钮可以选择文件夹将处理的的照片保存在本地。

原本在百度官方给出的文档中显示,最多上传不超过8m的数据包,但实际上在测试过程中,只要照片超过1m就会出现错误返回。所以添加了检测照片大小数据的功能,超过1m会提示用户照片数据过大,无法处理,需要重新上传。

实现代码如下:

import okhttp3.*;
import org.json.JSONObject;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import java.net.URLEncoder;
import java.util.Base64;

public class PhotoEnhancer extends JFrame {
    private static final String API_KEY = "T2ZS5mbDARSEIJKfSZrxr0ve";
    private static final String SECRET_KEY = "3y8zcki0ViAploSzUTr7Wq9BK5Q17qNk";
    private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();
    private JLabel originalLabel;
    private JLabel processedLabel;
    private BufferedImage originalImage;
    private BufferedImage processedImage;

    public PhotoEnhancer() {
        setTitle("图像增强清晰度软件");
        setSize(1600, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        JPanel topPanel = new JPanel(new GridLayout(1, 2));
        originalLabel = new JLabel();
        processedLabel = new JLabel();
        topPanel.add(new JScrollPane(originalLabel));
        topPanel.add(new JScrollPane(processedLabel));

        JPanel bottomPanel = new JPanel(); // 使用默认的 FlowLayout
       
bottomPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 700, 20)); // 水平居中,适当的水平和垂直间距
       
JButton uploadButton = new JButton("上传照片");
        JButton saveButton = new JButton("保存照片");
        uploadButton.addActionListener(this::uploadImage);
        saveButton.addActionListener(this::saveImage);
        bottomPanel.add(uploadButton);
        bottomPanel.add(saveButton);

        add(topPanel, BorderLayout.CENTER);
        add(bottomPanel, BorderLayout.SOUTH);
    }

    private void uploadImage(ActionEvent event) {
        JFileChooser fileChooser = new JFileChooser();
        if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            if (file.length() > 1024 * 1024) {
                JOptionPane.showMessageDialog(this, "上传的图片过大,请上传小于1M的图片。", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }
            try {
                originalImage = ImageIO.read(file);
                updateLabel(originalLabel, originalImage);
                processedImage = processImage(originalImage);
                updateLabel(processedLabel, processedImage);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private void updateLabel(JLabel label, BufferedImage image) {
        int labelWidth = label.getParent().getWidth(); // 使用父容器的宽度
       
int labelHeight = label.getParent().getHeight(); // 使用父容器的高度
       
int imageWidth = image.getWidth();
        int imageHeight = image.getHeight();

        double scaleX = (double) labelWidth / imageWidth;
        double scaleY = (double) labelHeight / imageHeight;
        double scale = Math.min(scaleX, scaleY);

        int scaledWidth = (int) (imageWidth * scale);
        int scaledHeight = (int) (imageHeight * scale);

        // 创建一个新的BufferedImage用于绘制居中的图片
       
BufferedImage centeredImage = new BufferedImage(labelWidth, labelHeight, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = centeredImage.createGraphics();

        // 清除背景并绘制居中的图片
       
g2d.setComposite(AlphaComposite.Clear);
        g2d.fillRect(0, 0, labelWidth, labelHeight);
        g2d.setComposite(AlphaComposite.SrcOver);
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g2d.drawImage(image, (labelWidth - scaledWidth) / 2, (labelHeight - scaledHeight) / 2, scaledWidth, scaledHeight, null);

        g2d.dispose();

        // 设置新的居中图片到JLabel
       
ImageIcon icon = new ImageIcon(centeredImage);
        label.setIcon(icon);
        label.revalidate();
        label.repaint();
    }

    private void saveImage(ActionEvent event) {
        if (processedImage != null) {
            JFileChooser fileChooser = new JFileChooser();
            if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                File file = fileChooser.getSelectedFile();
                try {
                    ImageIO.write(processedImage, "png", file);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private BufferedImage processImage(BufferedImage image) throws IOException {
        ByteArrayOutputStream bao = new ByteArrayOutputStream();
        ImageIO.write(image, "png", bao);
        byte[] imageBytes = bao.toByteArray();
        String base64Image = Base64.getEncoder().encodeToString(imageBytes);
        base64Image = URLEncoder.encode(base64Image, "utf-8");

        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "image=" + base64Image);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/rest/2.0/image-process/v1/image_definition_enhance?access_token=" + getAccessToken())
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .addHeader("Accept", "application/json")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

        String jsonResponse = response.body().string();
        JSONObject jsonResponseBody = new JSONObject(jsonResponse);
        String base64ImageResult = jsonResponseBody.getString("image");

        byte[] imageBytesDecoded = Base64.getDecoder().decode(base64ImageResult);
        ByteArrayInputStream bais = new ByteArrayInputStream(imageBytesDecoded);
        return ImageIO.read(bais);
    }

    static String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY);
        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .method("POST", body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();
        Response response = HTTP_CLIENT.newCall(request).execute();
        return new JSONObject(response.body().string()).getString("access_token");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new PhotoEnhancer().setVisible(true);
        });
    }
}

运行截图:

 

posted @ 2024-11-20 20:54  序章0  阅读(2)  评论(0编辑  收藏  举报