0

我有一张图片 (147 KB),我想将其缩小到 100KB 以下。下面的代码尝试这样做,但是当图像从另一侧出来时,宽度和高度会按比例缩小,但图像上的磁盘空间会从 147 变为 250!它应该变得更小而不是更高......

你能告诉我为什么这段代码没有这样做吗?

谢谢

//Save image
        BufferedImage resizeImagePng = resizeImage(originalImage, type, newLargeImageLocation);

    //Resize and save
    ImageIO.write(resizeImagePng, "png", new File(newSmallImageLocation));



//Create new image
    private static BufferedImage resizeImage(BufferedImage originalImage, int type, String newLargeLocation) throws Exception{

            //Get size of image
            File file =new File(newLargeLocation);

            //File size in KBs
            double bytes = file.length();
            double kiloBytes = bytes/1024;

            double smallWidth = originalImage.getWidth();
            double smallHeight = originalImage.getHeight();

            double downMult = 1;

            //If image is too large downsize to fit the size
            if (kiloBytes>MAX_IMAGE_SIZE_IN_KYLOBITES) {

                downMult = MAX_IMAGE_SIZE_IN_KYLOBITES/kiloBytes;

                smallWidth *= downMult;
                smallHeight *= downMult;
            }

            //Final dimensions
            int finalHeight = (int)smallHeight;
            int finalWidth = (int)smallWidth;

            //Init after
            BufferedImage after = new BufferedImage(finalWidth, finalHeight, BufferedImage.TYPE_INT_ARGB);

            //Scale
            AffineTransform at = new AffineTransform();
            at.scale(downMult, downMult);

            //Scale op
            AffineTransformOp scaleOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
            after = scaleOp.filter(originalImage, after);

            //Return after
            return after;
        }
4

1 回答 1

1

2个问题,我也有一个调整大小的程序,但我调整图像的大小有点不同:

首先,我从一个名为 original 的 BufferedImage 对象开始创建一个 Dimension 对象(不是真正需要,但在设计上看起来更好一些)

final int width = original.getWidth();
final int height = original.getHeight();
final Dimension d = new Dimension(width, height);

在我的例子中,它不是关于文件大小,而是关于最大宽度和/或高度,所以在不深入细节的情况下,我根据上面创建的对象计算一个新的 Dimension 对象。新的 Dimension 对象称为 scaled。

This is how I obtain a new scaled buffered image:

public BufferedImage resizeExact(final BufferedImage original, final Dimension scaled, final Dimension offset) {
    final Image newImage = original.getScaledInstance(scaled.width, scaled.height, Image.SCALE_SMOOTH);
    final BufferedImage bufferedImage = new BufferedImage(newImage.getWidth(null),
                                                          newImage.getHeight(null),
                                                          BufferedImage.TYPE_INT_BGR);
    bufferedImage.createGraphics().drawImage(newImage, offset.width, offset.height, null);
    return bufferedImage;
}

Using this code I obtain a BufferedImage called resizedImage that needs to get written to an OutputStream out, for this I use this code:

ImageIO.write(resized, "jpg", out);
out.close();

And here I am about the 2nd issue: I use the standard ImageIO class to write the BufferedImage as a jpeg file. The issue here is that JPEG encoders typically use a compression factor, the higher the factor the smaller the resulting file but the more quality loss in the resulting file. The code uses a default compression factor of 70%. which suits me fine. However if yoy want to change this, this reference explains how to do this: Setting jpg compression level with ImageIO in Java. Note that here changing it to 100% is essentially a lower compression factor.

Your code snippet doesn't show how eventually you create the jpeg file (I assume you use jpeg as well). If your original image is compressed say with a ratio of 40% (unlikely because then you get a lousy image I assume) so un-jpeged you have 100%, if you wanted to reduce the file size to 80% you reduce the image size to 80%, if you then compress it using 70% compression factor your end result will be aroung 56% which is bigger than the 40%.

Hope this helps. But if you specify how you write the jeg image (maybe using another library than the standard of javax.imageio) there might be another way to specify the compression factor.

于 2013-08-28T19:20:27.613 回答