希望以下内容对您有所帮助:
public static Bitmap getZoomBitmap(int mMaxWidth, int mMaxHeight,
InputStream in) {
Bitmap bitmap = null;
BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
// If we have to resize this image, first get the natural bounds.
decodeOptions.inJustDecodeBounds = true;
BitmapFactory.decodeStream(in, null, decodeOptions);
int actualWidth = decodeOptions.outWidth;
int actualHeight = decodeOptions.outHeight;
// Then compute the dimensions we would ideally like to decode to.
int desiredWidth = getResizedDimension(mMaxWidth, mMaxHeight,
actualWidth, actualHeight);
int desiredHeight = getResizedDimension(mMaxHeight, mMaxWidth,
actualHeight, actualWidth);
// Decode to the nearest power of two scaling factor.
decodeOptions.inJustDecodeBounds = false;
// TODO(ficus): Do we need this or is it okay since API 8 doesn't
// support it?
// decodeOptions.inPreferQualityOverSpeed =
// PREFER_QUALITY_OVER_SPEED;
int sampleSize = findBestSampleSize(actualWidth, actualHeight,
desiredWidth, desiredHeight);
decodeOptions.inSampleSize = sampleSize;
Bitmap tempBitmap = BitmapFactory.decodeStream(in, null, decodeOptions);
// If necessary, scale down to the maximal acceptable size.
if (tempBitmap != null
&& (tempBitmap.getWidth() > desiredWidth || tempBitmap
.getHeight() > desiredHeight)) {
bitmap = Bitmap.createScaledBitmap(tempBitmap, desiredWidth,
desiredHeight, true);
tempBitmap.recycle();
} else {
bitmap = tempBitmap;
}
return bitmap;
}
/**
* Scales one side of a rectangle to fit aspect ratio.
*
* @param maxPrimary
* Maximum size of the primary dimension (i.e. width for max
* width), or zero to maintain aspect ratio with secondary
* dimension
* @param maxSecondary
* Maximum size of the secondary dimension, or zero to maintain
* aspect ratio with primary dimension
* @param actualPrimary
* Actual size of the primary dimension
* @param actualSecondary
* Actual size of the secondary dimension
*/
public static int getResizedDimension(int maxPrimary, int maxSecondary,
int actualPrimary, int actualSecondary) {
// If no dominant value at all, just return the actual.
if (maxPrimary == 0 && maxSecondary == 0) {
return actualPrimary;
}
// If primary is unspecified, scale primary to match secondary's scaling
// ratio.
if (maxPrimary == 0) {
double ratio = (double) maxSecondary / (double) actualSecondary;
return (int) (actualPrimary * ratio);
}
if (maxSecondary == 0) {
return maxPrimary;
}
double ratio = (double) actualSecondary / (double) actualPrimary;
int resized = maxPrimary;
if (resized * ratio > maxSecondary) {
resized = (int) (maxSecondary / ratio);
}
return resized;
}
/**
* Returns the largest power-of-two divisor for use in downscaling a bitmap
* that will not result in the scaling past the desired dimensions.
*
* @param actualWidth
* Actual width of the bitmap
* @param actualHeight
* Actual height of the bitmap
* @param desiredWidth
* Desired width of the bitmap
* @param desiredHeight
* Desired height of the bitmap
*/
public static int findBestSampleSize(int actualWidth, int actualHeight,
int desiredWidth, int desiredHeight) {
double wr = (double) actualWidth / desiredWidth;
double hr = (double) actualHeight / desiredHeight;
double ratio = Math.min(wr, hr);
float n = 1.0f;
while ((n * 2) <= ratio) {
n *= 2;
}
return (int) n;
}