2016-04-25 19 views
0

写真が大きすぎる場合(たとえば、幅が2048pxを超える場合のみ)、カメラで撮影した各写真のサイズを変更したい場合。大きすぎる場合のみビットマップのサイズを変更する

私は、公式ドキュメント

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, 
    int reqWidth, int reqHeight) { 

    // First decode with inJustDecodeBounds=true to check dimensions 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeResource(res, resId, options); 

    // Calculate inSampleSize 
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); 

    // Decode bitmap with inSampleSize set 
    options.inJustDecodeBounds = false; 
    return BitmapFactory.decodeResource(res, resId, options); 
} 

public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) > reqHeight 
       && (halfWidth/inSampleSize) > reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 

    return inSampleSize; 
} 

に見てきたが、このコードは、私が最終的なサイズを知っていることを伴います。 私がやりたいことは、実際に大きすぎる場合は50%、ビットマップが大きすぎない場合は20%だけ減らすことです(スマートフォンのカメラに依存します...)

calculateInSampleSize()は私が欲しいと思っているようですが、 "例えば、解像度が2048x1536で、inSampleSizeが4でデコードされた画像は約512x384のビットマップを生成しますが、最終的な幅/高さを設定したくありません。私は小さいビットマップを取得するとき

はその後、私は再び最適化するために、

scaledBitmap.compress(CompressFormat.JPEG, 80, out); 

を作りたいです。

どうすればこの問題を解決できますか?

答えて

0

最後に、私は別のソリューションを選択しました:

public static void resizeBitmapOnFileSystem(String originalPath, File photoCompressedFile) throws IOException { 
    final BitmapFactory.Options options = new BitmapFactory.Options(); 
    options.inJustDecodeBounds = true; 
    BitmapFactory.decodeFile(originalPath, options); 

    int minimalLengthSide = 300; //Minimal length of the shorter side of the picture. Used to calculate the best 'scale' value. 
    int scale = calculateInSampleSize(options, minimalLengthSide, minimalLengthSide); 

    ByteArrayOutputStream out = null; 
    FileOutputStream fo = null; 
    Bitmap scaledBitmap = null; 
    try { 
     out = new ByteArrayOutputStream(); 
     fo = new FileOutputStream(photoCompressedFile); 

     scaledBitmap = loadScaledBitmap(originalPath, scale); 
     if (scaledBitmap != null) { 
      scaledBitmap.compress(CompressFormat.JPEG, 75, out); 
      fo.write(out.toByteArray()); 
     } 
    } finally { 
     IOUtils.closeQuietly(out); 
     IOUtils.closeQuietly(fo); 
     recycleQuietly(scaledBitmap); 
    } 
} 

/** 
* From offical Android documentation 
* @param options 
* @param reqWidth 
* @param reqHeight 
* @return 
*/ 
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { 
    // Raw height and width of image 
    final int height = options.outHeight; 
    final int width = options.outWidth; 
    int inSampleSize = 1; 

    if (height > reqHeight || width > reqWidth) { 

     final int halfHeight = height/2; 
     final int halfWidth = width/2; 

     // Calculate the largest inSampleSize value that is a power of 2 and keeps both 
     // height and width larger than the requested height and width. 
     while ((halfHeight/inSampleSize) > reqHeight 
       && (halfWidth/inSampleSize) > reqWidth) { 
      inSampleSize *= 2; 
     } 
    } 
    return inSampleSize; 
} 

resizeBitmapOnFileSystem()方法は非常に "便利" でない場合でも、トリックはminimalLengthSide変数です。私が望む短辺の最小長(ここでは300px)を設定し、calculateInSampleSize()メソッドは自動的に適切な縮尺を計算します。

比率は保持されていますが、私は使用しません。 Bitmap.createScaledBitmap(realImage, width, height, filter) 「高価」または効率が悪い可能性があります。

0

ビットマップの幅と高さをbitmap.getWidth()bitmap.getHeight()とすることができます。幅と高さを取得したら、どちらの値が小さいかを確認します。幅が高さよりも小さい場合は、valueという1つの変数にwidthを格納し、別の場合はheightを格納します。

そして、次のように値をチェックすることによってビットマップを圧縮することができます。

Bitmap bitmap = your bitmap; 

int width = bitmap.getWidth(); 
int height = bitmap.getHeight(); 

int value; 
if (width < height) { 
    value = width; 
} else { 
    value = height; 
} 

Bitmap scaledBitmap; 

if (value > 5000) { 
    scaledBitmap = bitmap.compress(CompressFormat.JPEG, 80, out); 
} else if (value > 4000) { 
    scaledBitmap = bitmap.compress(CompressFormat.JPEG, 60, out); 
} else if (value > 3000) { 
    scaledBitmap = bitmap.compress(CompressFormat.JPEG, 40, out); 
} else if (value > 2048) { 
    scaledBitmap = bitmap.compress(CompressFormat.JPEG, 20, out); 
} 
+0

これは正確に私が望むものではありません。なぜなら、私は各次元でテストをしたくないからです...しかし、それはおそらく動作します... – psv

関連する問題