获取正确尺寸的图像时出现问题。
为此,我有这种方法可以调整图像的大小,并且逻辑上需要进行一些小的更改以获取正确的图像大小:
private final Integer width = 170;
private final Integer height = 140;
private final Integer maxFeatImageHeight = 600;
private final Integer maxFeatImageWidth = 600;
/**
* @param featureImage .
* @return byte[]
* @throws Exception
*/
private byte[] resizeFeatureImage(MultipartFile featureImage) throws Exception
{
try
{
BufferedImage originalImage = ImageIO.read(featureImage.getInputStream());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
double featImageWidth = originalImage.getWidth();
double featImageHeight = originalImage.getHeight();
if (featImageHeight > maxFeatImageHeight || featImageWidth > maxFeatImageWidth)
{
// Sanity check on the input (division by zero, infinity):
if (featImageWidth <= 1 || featImageHeight <= 1) {
throw new IllegalArgumentException("Error ..." + featureImage);
}
// The scaling factors to reach to maxima on width and height:
double xScale = maxFeatImageWidth / featImageWidth;
double yScale = maxFeatImageHeight / featImageHeight;
// Proportional (scale width and height by the same factor):
double scale = Math.min(xScale, yScale);
// (Possibly) Do not enlarge:
scale = Math.min(1.0, scale);
int finalWidth = Math.min((int) Math.round(scale * featImageWidth), maxFeatImageWidth);
int finalHeight = Math.min((int) Math.round(scale * featImageHeight), maxFeatImageHeight);
double ratio = featImageWidth / featImageHeight;
// width is bigger then height
if (ratio > 1)
{
finalWidth = maxFeatImageWidth;
finalHeight = (int) Math.round(maxFeatImageHeight / ratio);
}
// height is bigger then width
else if (ratio < 1)
{
finalWidth = (int) Math.round(maxFeatImageWidth / ratio);
finalHeight = maxFeatImageHeight;
}
// width and height are equal
else
{
finalHeight = maxFeatImageHeight;
finalWidth = maxFeatImageWidth;
}
logger.info("[resizeFeatureImage] [FEATURE IMAGE RESIZE] Starting to resize feature Image");
Graphics2D g2d;
BufferedImage resizedImage;
if (featureImage.getContentType().contains("png"))
{
resizedImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_ARGB);
}
else
{
resizedImage = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_3BYTE_BGR);
}
g2d = resizedImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(ImageIO.read(featureImage.getInputStream()), 0, 0, finalWidth, finalHeight,
null);
g2d.dispose();
ImageIO.write(resizedImage, featureImage.getContentType().split("/")[1], baos);
logger.info("[resizeFeatureImage] [FEATURE IMAGE RESIZE] Feature image resized!");
return baos.toByteArray();
}
else
{
ImageIO.write(originalImage, featureImage.getContentType().split("/")[1], baos);
return baos.toByteArray();
}
}
catch (Exception e)
{
logger.warn("[resizeFeatureImage] [STATUS] - ERROR ");
logger.warn("[resizeFeatureImage] [EXCEPTION] " + e.getMessage(), e);
throw new IOException("The file you uploaded can be damaged or has incorrect encoding.");
}
}
因此,显示的每个图像都小于其所拥有的空间
在下图中,您可以看到有很多空白未被使用,这肯定意味着我的方法做错了,导致这种情况,我已经检查了很多次这种方法,而我没有我真的不知道为什么或会发生这种情况,如果有需要,谁能帮助我编辑此方法,我将非常感激。
图像显示如下:
答案 0 :(得分:2)
private static final int MAX_FEAT_IMAGE_WIDTH = 600;
private static final int MAX_FEAT_IMAGE_WIDTH = 600;
double featImageWidth = originalImage.getWidth();
double featImageHeight = originalImage.getHeight();
// Sanity check on the input (division by zero, infinity):
if (featImageWidth <= 1 || featImageHeight <= 1) {
throw new IllegalArgumentException("..." + featureImage);
}
// The scaling factors to reach to maxima on width and height:
double xScale = MAX_FEAT_IMAGE_WIDTH / featImageWidth;
double yScale = MAX_FEAT_IMAGE_HEIGHT / featImageHeight;
// Proportional (scale width and height by the same factor):
double scale = Math.min(xScale, yScale);
// (Possibly) Do not enlarge:
scale = Math.min(1.0, scale);
int finalWidth = Math.min((int) Math.round(scale * featImageWidth), MAX_FEAT_IMAGE_WIDTH);
int finalHeight = Math.min((int) Math.round(scale * featImageHeigth), MAX_FEAT_IMAGE_HEIGHT);
如您所见,我扭转了两件事,以保持比例缩放。在精神上使用比率(/
而不是比例因子(*
)似乎会更难。
分别确定宽度和高度的缩放比例,让我们选择最小缩放比例。
也可以决定不放大小图片。
答案 1 :(得分:2)
您仅考虑方向(对于垂直,ratio
<1,否则为水平或正方形)。这还不够;您必须考虑目标宽度/高度:
int sw = originalImage.getWidth();
int sh = originalImage.getHeight();
int swdh = sw * maxFeatImageHeight;
int shdw = sh * maxFeatImageWidth;
if (swdh < shdw) {
finalWidth = swdh / sh;
finalHeight = maxFeatImageHeight;
} else {
finalWidth = maxFeatImageWidth;
finalHeight = shdw / sw;
}
更新:
好的,让我们从秤开始:
double xScale = maxFeatImageWidth/featImageWidth;
double yScale = maxFeatImageHeight/featImageHeight;
您可以写:
在yScale 否则,我们可以使用xScale: 由于所有宽度和高度都> = 0,因此yScale 如此 我将这两个值另存为swdh和shdw,因为以后可以重用它们。 它避免了从finalWidth = featImageWidth*yScale = featImageWidth*maxFeatImageHeight/featImageHeight;
finalHeight = maxFeatImageHeight;
finalWidth = maxFeatImageWidth;
finalHeight = featImageHeight*xScale = featImageHeight*maxFeatImageWidth/featImageWidth;
yScale*featImageWidth*featImageHeight < xScale*featImageWidth*featImageHeight
maxFeatImageHeight*featImageWidth < maxFeatImageHeight*featImageWidth
int
到double
以及从double
到int
的转换。
答案 2 :(得分:1)
很可能您应该知道要调整大小的图像的大小,在该值之后,if and else语句应该起作用,并调用resize函数就可以调整大小。希望对您有所帮助。并且在调整大小时,请确保也能够按照用户定义减小像素。