Как правильно изменить размер изображения? - PullRequest
1 голос
/ 28 июня 2019

У меня проблема с получением нужного размера изображения.

Для этого у меня есть этот метод, который делает изменение размера изображения, и каким-то образом логике нужно небольшое изменение, чтобы получить правильный размер изображения:

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.");
    }
}

Таким образом, каждое изображение отображается меньше, чем пространство, которое она имеет на изображении ниже вы можете видеть, что есть много пустого пространства, которое не используется, и определенно это означает, что я делаю что-то не так в своем методе, который вызывает это, я много раз проверял этот метод, и я надеваю Не знаю, почему или это происходит, может кто-нибудь помочь мне отредактировать этот метод, если это необходимо, я был бы очень признателен. изображения показываются так: enter image description here

Ответы [ 3 ]

2 голосов
/ 28 июня 2019
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);
  • Как видите, я переворачиваю две вещи, чтобы поддерживать пропорциональное масштабирование. Использование соотношения (/) вместо коэффициента масштабирования (*), кажется, умственно затрудняет его.

  • Определение масштабирования по ширине и по высоте отдельно. Давайте выберем минимальное масштабирование.

  • Можно также решить, не , чтобы увеличить маленькие картинки.

2 голосов
/ 28 июня 2019

Вы учитываете только ориентацию (ratio <1 для вертикальной, в противном случае горизонтальной или квадратной). Этого не достаточно; необходимо учитывать целевую ширину / высоту: </p>

        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;
        }

UPDATE:

ОК, начнем с весов:

        double xScale = maxFeatImageWidth/featImageWidth;
        double yScale = maxFeatImageHeight/featImageHeight;

Вы можете написать:

В случае, когда yScale

finalWidth = featImageWidth*yScale = featImageWidth*maxFeatImageHeight/featImageHeight;
finalHeight = maxFeatImageHeight;

В противном случае мы можем использовать xScale:

finalWidth = maxFeatImageWidth;
finalHeight = featImageHeight*xScale = featImageHeight*maxFeatImageWidth/featImageWidth;

Поскольку все ширины и высоты> = 0, результат yScale

yScale*featImageWidth*featImageHeight < xScale*featImageWidth*featImageHeight

так

maxFeatImageHeight*featImageWidth < maxFeatImageHeight*featImageWidth

Я сохранил эти два значения как swdh и shdw, потому что они могут быть использованы позже.

Это позволяет избежать преобразований из int в double и из double в int.

1 голос
/ 28 июня 2019

Скорее всего, вы должны знать размер изображения для изменения размера, после того, как на основе этого значения должен работать оператор if и else, и, вызывая функцию resize, вы сможете изменить его размер. Надеюсь, это поможет. А когда вы изменяете размер, убедитесь, что вы можете уменьшить пиксель в соответствии с пользовательскими настройками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...