0
我试图处理一系列图像并将其保存到Google Cloud Storage,并在App Engine调整图像大小时遇到严重的图像质量问题。App Engine图像处理(JAVA)的图像质量问题
原始图像总是保存没有任何质量问题,但是当使用ImageServiceFactory调整大小时,图像保存得非常像素化。我意识到我应该缓冲输入流,但无法想象这会影响图像质量。
ImageServiceFactory是垃圾吗?
感谢您的帮助!
下面的代码:
public static void process(String path) {
Cover cover = null;
URL url = UrlBuilder.coverUrl(path);
try {
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
connection.setRequestMethod("HEAD");
connection.connect();
String contentType = connection.getContentType();
FileOutput output = new FileOutput(contentType);
OutputEncoding encoding = output.encoding;
// create Image object from InputStream.
InputStream imgStream = url.openStream();
byte[] imageBytes = ByteStreams.toByteArray(imgStream);
Image image = ImagesServiceFactory.makeImage(imageBytes);
// generated details for image path and file name.
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dir = sdf.format(book.getRelease());
String ext = output.extension;
// save original image
Image ogImage = resizeImage(image, encoding, image.getHeight(), 100);
String ogPath = dir + "/" + book.getItemCode() + "." + ext;
String ogLocation = saveImage(ogPath, ogImage);
// save md image
Image mdImage = resizeImage(image, encoding, MD_HEIGHT, 100);
String mdPath = dir + "/" + book.getItemCode() + "_MD." + ext;
String mdLocation = saveImage(mdPath, mdImage);
} catch(IOException e) {
e.printStackTrace();
}
}
private static Image resizeImage(Image image, OutputEncoding encoding, int height, int quality) {
// create output settings and set image quality.
OutputSettings settings = new OutputSettings(encoding);
settings.setQuality(quality);
// Get an instance of the imagesService to transform images.
ImagesService imagesService = ImagesServiceFactory.getImagesService();
int width = (int) Math.floor(height * image.getWidth()/image.getHeight());
Transform transform = ImagesServiceFactory.makeResize(width, height, false);
Image resizedImage = imagesService.applyTransform(transform, image, settings);
return resizedImage;
}
private static String saveImage(String fileName, Image image) {
byte[] content = image.getImageData();
Storage storage = StorageOptions.getDefaultInstance().getService();
// Modify access list to allow all users with link to read file
List<Acl> acls = new ArrayList<>();
acls.add(Acl.of(Acl.User.ofAllUsers(), Acl.Role.READER));
BlobInfo info = BlobInfo.newBuilder(bucket, fileName).setAcl(acls).build();
// the inputstream is closed by default, so we don't need to close it here
Blob blob = storage.create(info, content);
// return the public download link
return blob.getMediaLink();
}
private static class FileOutput {
public String extension;
public OutputEncoding encoding;
public FileOutput(String mimeType) {
switch(mimeType) {
case "image/png":
extension = "png";
encoding = ImagesService.OutputEncoding.PNG;
break;
case "image/jpeg":
default:
extension = "jpg";
encoding = ImagesService.OutputEncoding.JPEG;
break;
}
}
}