2024.12.13
图像处理
package org.example; import okhttp3.*; import org.json.JSONObject; import javax.swing.*; import java.awt.*; import java.io.*; import java.net.URLEncoder; import java.nio.file.Files; import java.util.Base64; public class ImageStyleTransformUI { public static final String API_KEY = "SeuSJeVKt4Yr9T3cSlEhiYJm"; public static final String SECRET_KEY = "WE5uoeW90HeGVrdUIvZM3jGkPqPv1hmw"; static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build(); public static void main(String[] args) { // 创建主窗口 JFrame frame = new JFrame("图像特效处理工具"); frame.setSize(800, 600); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); // 顶部选择图片按钮 JButton selectFileButton = new JButton("选择图片"); JLabel selectedFileLabel = new JLabel("未选择图片"); JPanel topPanel = new JPanel(); topPanel.add(selectFileButton); topPanel.add(selectedFileLabel); // 中间显示原图和处理后图片的区域 JPanel imagePanel = new JPanel(); imagePanel.setLayout(new GridLayout(1, 2, 10, 10)); // 网格布局,左右对比 JLabel originalImageLabel = new JLabel("原图", SwingConstants.CENTER); originalImageLabel.setVerticalAlignment(SwingConstants.TOP); JLabel processedImageLabel = new JLabel("处理后图片", SwingConstants.CENTER); processedImageLabel.setVerticalAlignment(SwingConstants.TOP); imagePanel.add(originalImageLabel); imagePanel.add(processedImageLabel); // 底部提交按钮 JButton processButton = new JButton("处理图片"); processButton.setEnabled(false); JPanel bottomPanel = new JPanel(); bottomPanel.add(processButton); // 添加组件到主窗口 frame.add(topPanel, BorderLayout.NORTH); frame.add(imagePanel, BorderLayout.CENTER); frame.add(bottomPanel, BorderLayout.SOUTH); // 选择文件功能 final File[] selectedFile = {null}; selectFileButton.addActionListener(e -> { JFileChooser fileChooser = new JFileChooser(); int returnValue = fileChooser.showOpenDialog(null); if (returnValue == JFileChooser.APPROVE_OPTION) { selectedFile[0] = fileChooser.getSelectedFile(); selectedFileLabel.setText("已选择: " + selectedFile[0].getName()); processButton.setEnabled(true); // 显示原图预览 ImageIcon icon = new ImageIcon(new ImageIcon(selectedFile[0].getAbsolutePath()) .getImage() .getScaledInstance(400, 300, Image.SCALE_SMOOTH)); originalImageLabel.setIcon(icon); originalImageLabel.setText(""); processedImageLabel.setIcon(null); processedImageLabel.setText("处理后图片"); } }); // 处理图片功能 processButton.addActionListener(e -> { if (selectedFile[0] == null) { JOptionPane.showMessageDialog(frame, "请先选择图片!", "错误", JOptionPane.ERROR_MESSAGE); return; } try { // 调用特效处理函数 String resultPath = applyStyleTransform(selectedFile[0]); ImageIcon resultIcon = new ImageIcon(new ImageIcon(resultPath) .getImage() .getScaledInstance(400, 300, Image.SCALE_SMOOTH)); processedImageLabel.setIcon(resultIcon); processedImageLabel.setText(""); } catch (Exception ex) { JOptionPane.showMessageDialog(frame, "处理失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE); } }); // 显示窗口 frame.setVisible(true); } /** * 调用百度 API 对图片进行特效处理 * * @param imageFile 选择的图片文件 * @return 处理后的图片文件路径 * @throws IOException 异常 */ public static String applyStyleTransform(File imageFile) throws IOException { // 获取 Access Token String accessToken = getAccessToken(); // 编码图片为 Base64 String base64Image = encodeImageToBase64(imageFile); // 构造请求体 String requestBodyData = "option=cartoon&image=" + base64Image; // 使用卡通化特效 RequestBody body = RequestBody.create( MediaType.parse("application/x-www-form-urlencoded"), requestBodyData ); // 构造请求 Request request = new Request.Builder() .url("https://aip.baidubce.com/rest/2.0/image-process/v1/style_trans?access_token=" + accessToken) .method("POST", body) .addHeader("Content-Type", "application/x-www-form-urlencoded") .build(); // 发送请求并处理响应 Response response = HTTP_CLIENT.newCall(request).execute(); String responseBody = response.body().string(); System.out.println("API Response: " + responseBody); // 解析响应 JSONObject jsonObject = new JSONObject(responseBody); if (jsonObject.has("error_code")) { throw new IOException("API 错误: " + jsonObject.getString("error_msg")); } String resultImageBase64 = jsonObject.getString("image"); // 保存结果图片 byte[] decodedBytes = Base64.getDecoder().decode(resultImageBase64); File resultFile = new File("result_image.jpg"); try (OutputStream os = new FileOutputStream(resultFile)) { os.write(decodedBytes); } return resultFile.getAbsolutePath(); } /** * 获取百度 API 的 Access Token * * @return 鉴权签名(Access Token) * @throws IOException 异常 */ public static String getAccessToken() throws IOException { MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); String requestBodyData = "grant_type=client_credentials&client_id=" + API_KEY + "&client_secret=" + SECRET_KEY; RequestBody body = RequestBody.create(mediaType, requestBodyData); 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(); String responseBody = response.body().string(); JSONObject jsonObject = new JSONObject(responseBody); return jsonObject.getString("access_token"); } /** * 将图片文件编码为 Base64 * * @param imageFile 图片文件 * @return Base64 编码字符串 * @throws IOException 异常 */ public static String encodeImageToBase64(File imageFile) throws IOException { if (!imageFile.exists() || !imageFile.isFile()) { throw new FileNotFoundException("文件不存在或不是有效的文件:" + imageFile.getAbsolutePath()); } byte[] imgData = Files.readAllBytes(imageFile.toPath()); String base64 = Base64.getEncoder().encodeToString(imgData); return URLEncoder.encode(base64, "utf-8"); } }