【发布时间】:2021-07-25 20:31:34
【问题描述】:
我从来没有在 java 中处理过图片,我是这方面的初学者。 我需要制作一个函数,根据图像中间的一定宽度和高度比例裁剪图像。
通过 REST Api,我收到一个 MultipartFile,我将其传递给图像裁剪功能。我使用 file.getBytes() 转发图像。
以下是我如何编写图像裁剪功能的代码:
public static byte[] cropImage(byte[] data) {
ByteArrayInputStream bais = new ByteArrayInputStream(data);
try {
BufferedImage img = ImageIO.read(bais);
int width = img.getWidth();
int height = img.getHeight();
float aspectRatio = (float) 275 / (float) 160;
int destWidth;
int destHeight;
int startX;
int startY;
if(width/height > aspectRatio) {
destHeight = height;
destWidth = Math.round(aspectRatio * height);
startX = Math.round(( width - destWidth ) / 2);
startY = 0;
} else if (width/height < aspectRatio) {
destWidth = width;
destHeight = Math.round(width / aspectRatio);
startX = 0;
startY = Math.round((height - destHeight) / 2);
} else {
destWidth = width;
destHeight = height;
startX = 0;
startY = 0;
}
BufferedImage dst = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_ARGB);
dst.getGraphics().drawImage(img, 0, 0, destWidth, destHeight, startX, startY, startX + destWidth, startY + destHeight, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(dst, "png", baos);
return baos.toByteArray();
} catch (IOException e) {
throw new RuntimeException("IOException in scale");
}
}
但是当我裁剪图像时,结果是一个尺寸比接收到的图像大得多的图像。我需要有关如何解决此问题的帮助。
编辑:
根据this的回答,这部分代码变大了:
ImageIO.read (bais)
有没有其他方法可以将图像从字节数组转换为缓冲图像但保持原始图像的大小?
【问题讨论】:
-
我想知道生成的图像是否有与原始图像不同的特征。例如每种颜色的位数。一种方法可能是使用标准工具并进行相同的调整大小,然后比较它们生成的图像和生成的图像的特征。 Gimp 或 imagemagick 可能对此有好处。
-
宽/高为整数除法,请改用float或double变量
-
并且,添加到@DonBranson 评论,AFAIK 您正在使用默认(即中等)png 压缩,不知道它是否以及影响结果的程度,但这个旧答案中有一些有用的信息:stackoverflow.com/questions/2721303/…
-
首先,如果您明确表示您在谈论 file 大小,而不是图像“大小”(即图像尺寸),这将有助于解决这个问题。其次,图像的内存表示与文件大小不(直接)相关,因此链接的答案/代码不是那么相关。最后,您选择存储图像的格式是 PNG。如果您的输入是 JPEG 格式的“自然图像”(即照片),则应该会增加尺寸,因为此类图像的压缩效率要低得多(但无损)。您的问题应该指定输入格式和示例图像。 ??????
-
PS:你可能想看看
BufferedImage.getSubimage(x, y, w, h)。
标签: java bufferedimage javax.imageio multipartfile