0

画像 (147 KB) があり、100 KB 未満に縮小したいと考えています。以下のコードはこれを試みますが、画像が反対側に表示されると、幅と高さが縮小されますが、画像のディスク容量は 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つの問題、サイズ変更プログラムもありますが、画像のサイズを少し変更します:

最初に、元の BufferedImage オブジェクトから開始して Dimension オブジェクトを作成します (実際には必要ありませんが、設計上は少し優れているようです)。

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

私の場合、それはファイルサイズではなく、最大の幅や高さに関するものなので、詳細には触れずに、上記で作成したオブジェクトに基づいて新しい Dimension オブジェクトを計算します。新しい Dimension オブジェクトは、scaled と呼ばれます。

これは、新しいスケーリングされたバッファリングされた画像を取得する方法です。

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

このコードを使用して、OutputStream アウトに書き込む必要がある resizedImage という BufferedImage を取得します。これには、次のコードを使用します。

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

そして、ここで 2 番目の問題について説明します。標準の ImageIO クラスを使用して、BufferedImage を jpeg ファイルとして書き込みます。ここでの問題は、JPEG エンコーダーは通常、圧縮係数を使用することです。係数が高いほど、結果のファイルは小さくなりますが、結果のファイルの品質が低下します。このコードでは、デフォルトの圧縮率 70% を使用しています。それは私にぴったりです。ただし、これを変更したい場合は、このリファレンスでこれを行う方法について説明しています: Java で ImageIO を使用して jpg 圧縮レベルを設定する。ここで 100% に変更すると、本質的に圧縮係数が低くなることに注意してください。

あなたのコード スニペットは、最終的に jpeg ファイルを作成する方法を示していません (jpeg も使用していると思います)。元の画像が40%の比率で圧縮されている場合(おそらく、お粗末な画像が得られる可能性は低いと思います)、JPEGではないため、ファイルサイズを80%に縮小したい場合は、画像サイズを縮小します70% の圧縮係数を使用して圧縮すると、最終結果は約 56% になり、40% よりも大きくなります。

お役に立てれば。しかし、jeg 画像の書き方を指定すると (javax.imageio の標準とは別のライブラリを使用する可能性があります)、圧縮率を指定する別の方法があるかもしれません。

于 2013-08-28T19:20:27.613 に答える