11月21日
任务四:
这个任务在任务三的基础上更换所调用的api即可,都是相同的模块,可以将任务三和四放在一个同一个软件中,让用户选择想做的操作。
因为图像特效的操作和图像增强的操作几乎一样,所以我们编写了一个父类定义了基本的图像上传和下载保存操作,两个子类只需要分别重写图像特效和图像增强的具体操作就行。
实现代码如下:
//UI界面
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
public class PhotoEnhancerUI {
private JFrame frame;
private JLabel originalLabel;
private JLabel processedLabel;
private JButton uploadButton;
private JButton saveButton;
private JComboBox<String>
effectComboBox;
public PhotoEnhancerUI() {
frame = new JFrame("图像处理软件");
frame.setSize(1600, 800);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.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 effectPanel = new
JPanel(new FlowLayout(FlowLayout.CENTER));
effectComboBox = new JComboBox<>(new
String[]{"图像去雾", "图像动漫化"});
effectComboBox.setPreferredSize(new Dimension(200, 30)); // 宽度为200,高度为30
effectComboBox.setMinimumSize(new
Dimension(200, 30));
effectComboBox.setMaximumSize(new Dimension(200, 30));
Font font =
effectComboBox.getFont().deriveFont(Font.BOLD, 20);
effectComboBox.setFont(font);
effectPanel.add(effectComboBox);
JPanel bottomPanel = new
JPanel(new FlowLayout(FlowLayout.CENTER, 700, 20));
uploadButton = new
JButton("上传照片");
saveButton = new
JButton("保存照片");
uploadButton.addActionListener(this::uploadImage);
saveButton.addActionListener(this::saveImage);
bottomPanel.add(uploadButton);
bottomPanel.add(saveButton);
frame.add(effectPanel,
BorderLayout.NORTH);
frame.add(topPanel,
BorderLayout.CENTER);
frame.add(bottomPanel,
BorderLayout.SOUTH);
}
public void setVisible() {
frame.setVisible(true);
}
public void
uploadImage(ActionEvent event) {
JFileChooser fileChooser =
new JFileChooser();
if
(fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
File file =
fileChooser.getSelectedFile();
PhotoEnhancerLogic logic
= new PhotoEnhancerLogic();
if ("图像去雾".equals(effectComboBox.getSelectedItem())) {
logic.uploadImage(file, originalLabel, processedLabel);
} else {
PhotoEffectLogic
effectLogic = new PhotoEffectLogic();
effectLogic.uploadImage(file, originalLabel, processedLabel);
}
}
}
public void saveImage(ActionEvent
event) {
JFileChooser fileChooser =
new JFileChooser();
if
(fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
File file =
fileChooser.getSelectedFile();
try {
ImageIO.write(getBufferedImageFromLabel(processedLabel),
"png", file);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public JLabel getOriginalLabel()
{
return originalLabel;
}
public static BufferedImage
getBufferedImageFromLabel(JLabel label) {
Icon icon =
label.getIcon();
if (icon instanceof ImageIcon) {
ImageIcon imageIcon = (ImageIcon)
icon;
Image image =
imageIcon.getImage();
// 创建一个新的BufferedImage,其类型与屏幕兼容
BufferedImage
bufferedImage = new BufferedImage(label.getWidth(), label.getHeight(),
BufferedImage.TYPE_INT_ARGB);
// 获取Graphics2D上下文并绘制图像
Graphics2D
g2d = bufferedImage.createGraphics();
// 清除之前的内容
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(0, 0,
label.getWidth(), label.getHeight());
// 绘制图像
g2d.setComposite(AlphaComposite.SrcOver);
g2d.drawImage(image, 0, 0,
label.getWidth(), label.getHeight(), null);
g2d.dispose();
return bufferedImage;
}
return null;
}
public static void main(String[]
args) {
SwingUtilities.invokeLater(()
-> {
new
PhotoEnhancerUI().setVisible();
});
}
}
//图像操作父类
import okhttp3.*;
import org.json.JSONObject;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public abstract class ImageProcessor {
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 BufferedImage processedImage;
private BufferedImage x;
protected void updateLabel(JLabel
label, BufferedImage image) {
int labelWidth =
label.getWidth();
int labelHeight =
label.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 centeredImage = new
BufferedImage(labelWidth, labelHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d =
centeredImage.createGraphics();
g2d.drawImage(image, (labelWidth
- scaledWidth) / 2, (labelHeight - scaledHeight) / 2, scaledWidth,
scaledHeight, null);
g2d.dispose();
ImageIcon icon = new
ImageIcon(centeredImage);
label.setIcon(icon);
label.revalidate();
label.repaint();
}
public void uploadImage(File file,
JLabel originalLabel, JLabel processedLabel) {
if (file.length() > 1024 *
1024) {
JOptionPane.showMessageDialog(null,
"上传的图片过大,请上传小于1M的图片。", "错误",
JOptionPane.ERROR_MESSAGE);
return;
}
try {
BufferedImage originalImage =
ImageIO.read(file);
x=originalImage;
updateLabel(originalLabel,
originalImage);
processedImage =
processImage(originalImage);
updateLabel(processedLabel,
processedImage);
} catch (IOException e) {
e.printStackTrace();
}
}
protected abstract BufferedImage
processImage(BufferedImage originalImage) throws IOException;
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");
}
}
//图像特效子类
import okhttp3.*;
import org.json.JSONObject;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Base64;
public class PhotoEffectLogic extends ImageProcessor{
private static final OkHttpClient
HTTP_CLIENT = new OkHttpClient().newBuilder().build();
@Override
protected 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,
"type=anime&image=" + base64Image);
Request request = new Request.Builder()
.url("https://aip.baidubce.com/rest/2.0/image-process/v1/selfie_anime?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);
}
}
//图像增强子类
import okhttp3.*;
import org.json.JSONObject;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Base64;
public class PhotoEnhancerLogic extends ImageProcessor {
private static final OkHttpClient
HTTP_CLIENT = new OkHttpClient().newBuilder().build();
protected 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);
}
}
运行截图如下: