mateclaw/mateclaw-server/src/main/java/vip/mate/tool/image/ImageFileDownloader.java

75 lines
2.5 KiB
Java

package vip.mate.tool.image;
import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
/**
* 图片文件下载器 — 从 provider CDN 下载图片到本地存储,或解码 Base64 图片
*
* @author MateClaw Team
*/
@Slf4j
@Component
public class ImageFileDownloader {
private static final Path UPLOAD_ROOT = Paths.get("data", "chat-uploads");
/**
* 从 URL 下载图片到本地
*/
public Path download(String imageUrl, String conversationId, String taskId, int index) throws IOException {
Path dir = UPLOAD_ROOT.resolve(conversationId);
Files.createDirectories(dir);
String extension = guessExtension(imageUrl);
String fileName = "image_" + taskId + "_" + index + extension;
Path targetFile = dir.resolve(fileName);
log.info("[ImageDownloader] Downloading image from {} to {}", imageUrl, targetFile);
long size = HttpUtil.downloadFile(imageUrl, targetFile.toFile());
log.info("[ImageDownloader] Downloaded {} bytes to {}", size, targetFile);
return targetFile;
}
/**
* 将 Base64 编码的图片保存到本地
*/
public Path saveBase64(String base64Data, String conversationId, String taskId, int index) throws IOException {
Path dir = UPLOAD_ROOT.resolve(conversationId);
Files.createDirectories(dir);
String fileName = "image_" + taskId + "_" + index + ".png";
Path targetFile = dir.resolve(fileName);
byte[] imageBytes = Base64.getDecoder().decode(base64Data);
Files.write(targetFile, imageBytes);
log.info("[ImageDownloader] Saved base64 image ({} bytes) to {}", imageBytes.length, targetFile);
return targetFile;
}
/**
* 构造文件的 API 访问 URL
*/
public String toServingUrl(String conversationId, Path localPath) {
return "/api/v1/chat/files/" + conversationId + "/" + localPath.getFileName().toString();
}
private String guessExtension(String url) {
String lower = url.toLowerCase().split("\\?")[0];
if (lower.endsWith(".png")) return ".png";
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return ".jpg";
if (lower.endsWith(".webp")) return ".webp";
if (lower.endsWith(".gif")) return ".gif";
return ".png";
}
}