2017-04-18 16 views
0

画像をサイズ変更して(ファイルとして保存する)、あらかじめ定義されたファイルサイズ(私の場合は512 KB) )。このメソッドが実行されるとAndroid - 画像サイズを縮小しても同じ割合でサイズが縮小されない

private static final int maximumFileSizeInKBs = 512; 

public static Uri resizeImage(Context context, Uri imageUri) { 
    // get image width and height 
    BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    Bitmap imageBitmap = BitmapFactory.decodeFile(new File(imageUri.getPath()).getAbsolutePath(), options); 
    int imageWidth = options.outWidth; 
    int imageHeight = options.outHeight; 

    // get image file size (in KBs) 
    File file = new File(imageUri.getPath()); 
    int fileSizeInKBs = Integer.parseInt(String.valueOf(file.length()/1024)); 

    // get the scaling factor 
    // (square root because when we scale both the width and height by the 
    // square root of the scaling factor, then the size of the final image 
    // will be scaled by the scaling factor) 
    double scalingFactor = Math.sqrt(fileSizeInKBs/maximumFileSizeInKBs); 

    // no need to scale if file already within maximum file size limit 
    if(scalingFactor <= 1) { 
     return imageUri; 
    } 

    // get scaled dimensions 
    int scaledImageWidth = (int) Math.floor(imageWidth/scalingFactor); 
    int scaledImageHeight = (int) Math.floor(imageHeight/scalingFactor); 

    // load original bitmap (load a scaled copy to avoid OutOfMemory errors) 
    options = new BitmapFactory.Options(); 
    options.inSampleSize = Math.max(imageHeight/scaledImageWidth, imageHeight/scaledImageHeight); 
    imageBitmap = BitmapFactory.decodeFile(new File(imageUri.getPath()).getAbsolutePath(), options); 

    // the scaled image above will be scaled by a value equal to the 
    // nearest power of 2, hence it wont be scaled to the exact value 
    // that we want. So, we need to calculate new scaling factors 
    // based on the scaled loaded bitmap 
    Matrix m = new Matrix(); 
    RectF inRect = new RectF(0, 0, imageWidth, imageHeight); 
    RectF outRect = new RectF(0, 0, scaledImageWidth, scaledImageHeight); 
    m.setRectToRect(inRect, outRect, Matrix.ScaleToFit.CENTER); 
    float[] values = new float[9]; 
    m.getValues(values); 

    // create a scaled bitmap with required file size 
    Bitmap scaledBitmap = Bitmap.createScaledBitmap(imageBitmap, (int) (imageWidth*values[0]), (int) (imageHeight*values[4]), true); 

    // delete original image 
    new File(imageUri.getPath()).delete(); 

    // write bitmap to file 
    File newImageFile = BaseResourceClass.makeTempResourceFile(Slide.ResourceType.IMAGE, context); 
    try { 
     newImageFile.createNewFile(); 
     FileOutputStream fos = new FileOutputStream(newImageFile); 
     scaledBitmap.compress(Bitmap.CompressFormat.PNG, 1, fos); 
     fos.close(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     Toast.makeText(context, "Something went wrong", Toast.LENGTH_SHORT).show(); 
    } 

    // recycle bitmaps to reallocate memory 
    Storage.recycleBitmap(imageBitmap); 
    Storage.recycleBitmap(scaledBitmap); 

    // scaling done, return new Image 
    return Uri.fromFile(newImageFile); 
} 

、画像寸法は(私はそれがあることを期待するもののように)正確なサイズに縮小ますが、KBの中の画像のサイズが縮小されていません。この方法は、以下のようになります同じ要因で例えば、私は次の番号に

before resizing 
imageWidth : 3120, imageHeight : 4160, fileSize : 2960 KB 

after resizing 
imageWidth : 1395, imageHeight : 1860, fileSize : 2491 KB 

を取得しています。このメソッドを実行した後、私は画像から非常に多くのピクセルを削除した後、それを維持するようにとても多くのスペースを占有している何であることを理解していません画像ファイルのサイズはこれほどです。他のStackOverflowの質問やAndroidのBitmapFactory、ビットマップクラスのドキュメントを見ようとしましたが、この問題はどこにも言及されていません。どんな助けもありがとう!

答えて

1

これは、読んでいる画像の種類(JPG、GIF、PNG、BMP)、圧縮された画質(JPGの場合) 、およびイメージのサイズを縮小した後の保存方法について説明します。

あなたの例では、あなたが使用したもの、画像表示されていないか、画像を使用した圧縮の種類。しかし、私はあなたがPNG画像として保存している参照してくださいコードから。

2MBの高品質のjpgイメージを使用していて、サイズを縮小してPNG(無駄な品質)として保存すると、以前よりも大きなファイルになる可能性があります。

JPG画像は圧縮アルゴリズムを使用して、できるだけ元の画像に似ていますが、スペースを大幅に少なくします。画質にもよりますが、大きなファイルサイズの画像や、わずか数キロバイトの画像が表示されます。あなたはPNGなどの画像を保存すると

は、あなたが(それはloselessと呼ばれる理由です)、あなたのオリジナルとまったく同じ画像を取得し、その方法は、あなたが圧縮により多くのファイルサイズを保存することはできません。

PNGを入力として使用し、縮小版をPNG形式で保存すると、「比例ファイルサイズ」の考え方に近いはずです。サイズを小さくすると、アンチエイリアス処理によって結果の画像に新しい色が作成され、圧縮のパフォーマンスが少し低下する可能性があります。 JPG画像を使用した作業

は、元の画像で使用された品質とあなたが結果を圧縮するために使用するものとして、それはもう少し予測不可能になり、両方の影響はのファイルサイズを引き起こします。

0

あなたは、画像が圧縮されていない場合は、あなたのイメージファイルのサイズは、画像の幅×高さに比例するよう期待することができます。 BMP形式の場合にのみ当てはまります。

PNG形式で保存された画像を処理しています。 PNGは画像を保存するために圧縮を使用します。そのため、画像のサイズは、画像の細かさによりますが、画像の幅は&の高さに依存します。

あなたのケースでは、イメージサイズは第2パラメータ、品質に最も依存します。

scaledBitmap.compress(Bitmap.CompressFormat.PNG、、fos);

ファイルを小さくするために0に変更できます。

image

関連する問題