转 图片操作类

package com.zuzhili.framework.utils;
   
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.graphics.BitmapFactory;
  import android.widget.ImageView;
   
  import com.android.volley.VolleyError;
  import com.android.volley.toolbox.ImageLoader;
  import com.lidroid.xutils.util.LogUtils;
   
  import java.io.File;
  import java.io.FileNotFoundException;
  import java.io.FileOutputStream;
   
  /**
  * Created by liutao on 14-3-18.
  */
  public class VolleyImageUtils {
   
  /**
  * 获取缩放的bitmap
  * @param filePath
  * @param maxWidth
  * @param maxHeight
  * @return
  */
  public static Bitmap getScaledBitmap(String filePath, int maxWidth, int maxHeight) {
  BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
  Bitmap bitmap = null;
  // If we have to resize this image, first get the natural bounds.
  decodeOptions.inJustDecodeBounds = true;
  BitmapFactory.decodeFile(filePath, decodeOptions);
  int actualWidth = decodeOptions.outWidth;
  int actualHeight = decodeOptions.outHeight;
   
  // Then compute the dimensions we would ideally like to decode to.
  int desiredWidth = getResizedDimension(maxWidth, maxHeight,
  actualWidth, actualHeight);
  int desiredHeight = getResizedDimension(maxHeight, maxWidth,
  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;
  decodeOptions.inSampleSize =
  findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
  Bitmap tempBitmap = BitmapFactory.decodeFile(filePath, 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;
  }
   
  /**
  * 获取缩放的bitmap
  * @param file
  * @param maxWidth
  * @param maxHeight
  * @return
  */
  public static Bitmap getScaledBitmap(File file, int maxWidth, int maxHeight) {
  BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
  Bitmap bitmap = null;
  // If we have to resize this image, first get the natural bounds.
  decodeOptions.inJustDecodeBounds = true;
  BitmapFactory.decodeFile(file.getAbsolutePath(), decodeOptions);
  int actualWidth = decodeOptions.outWidth;
  int actualHeight = decodeOptions.outHeight;
   
  // Then compute the dimensions we would ideally like to decode to.
  int desiredWidth = getResizedDimension(maxWidth, maxHeight,
  actualWidth, actualHeight);
  int desiredHeight = getResizedDimension(maxHeight, maxWidth,
  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;
  decodeOptions.inSampleSize =
  findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
  Bitmap tempBitmap = BitmapFactory.decodeFile(file.getAbsolutePath(), 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;
  }
   
  /**
  * 获取缩放的bitmap
  * @param context
  * @param imageResId
  * @param maxWidth
  * @param maxHeight
  * @return
  */
  public static Bitmap getScaledBitmap(Context context, int imageResId, int maxWidth, int maxHeight) {
  BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
  Bitmap bitmap = null;
  // If we have to resize this image, first get the natural bounds.
  decodeOptions.inJustDecodeBounds = true;
  BitmapFactory.decodeResource(context.getResources(), imageResId, decodeOptions);
  int actualWidth = decodeOptions.outWidth;
  int actualHeight = decodeOptions.outHeight;
   
  // Then compute the dimensions we would ideally like to decode to.
  int desiredWidth = getResizedDimension(maxWidth, maxHeight,
  actualWidth, actualHeight);
  int desiredHeight = getResizedDimension(maxHeight, maxWidth,
  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;
  decodeOptions.inSampleSize =
  findBestSampleSize(actualWidth, actualHeight, desiredWidth, desiredHeight);
  Bitmap tempBitmap = BitmapFactory.decodeResource(context.getResources(), imageResId, 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;
  }
   
  /**
  * 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
  */
  // Visible for testing.
  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;
  }
   
  /**
  * 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;
  }
   
  /**
  * 获取图片实际尺寸
  * @param imagePath
  * @return
  */
  public static int[] getActualImageDimension(String imagePath) {
  int[] imageSize = new int[2];
  BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
  // If we have to resize this image, first get the natural bounds.
  decodeOptions.inJustDecodeBounds = true;
  BitmapFactory.decodeFile(imagePath, decodeOptions);
  int actualWidth = decodeOptions.outWidth;
  int actualHeight = decodeOptions.outHeight;
  imageSize[0] = actualWidth;
  imageSize[1] = actualHeight;
  return imageSize;
  }
   
  /**
  * 获取图片实际尺寸
  * @param imageResId
  * @return
  */
  public static int[] getActualImageDimension(Context context, int imageResId) {
  int[] imageSize = new int[2];
  BitmapFactory.Options decodeOptions = new BitmapFactory.Options();
  // If we have to resize this image, first get the natural bounds.
  decodeOptions.inJustDecodeBounds = true;
  BitmapFactory.decodeResource(context.getResources(), imageResId, decodeOptions);
  int actualWidth = decodeOptions.outWidth;
  int actualHeight = decodeOptions.outHeight;
  imageSize[0] = actualWidth;
  imageSize[1] = actualHeight;
  return imageSize;
  }
   
  /**
  * 根据显示的最大宽度或最大高度,保持原图的宽高比缩放
  * @param imagePath 图片路径
  * @param maxWidth 图片显示的最大宽度
  * @param maxHeight 图片显示的最大高度
  * @return
  */
  public static int[] getDesiredImageDimension(String imagePath, int maxWidth, int maxHeight) {
  int[] desiredImageDimension = new int[2];
  int[] actualImageDimension = getActualImageDimension(imagePath);
  LogUtils.e("actual width: " + actualImageDimension[0] + ", actual height: " + actualImageDimension[1]);
  int maxPrimary;
  int maxSecondary;
  if (actualImageDimension[0] >= actualImageDimension[1]) {
  maxPrimary = maxWidth;
  maxSecondary = 0;
  desiredImageDimension[0] = getResizedDimension(maxPrimary, maxSecondary, actualImageDimension[0], actualImageDimension[1]);
  desiredImageDimension[1] = getResizedDimension(maxSecondary, maxPrimary, actualImageDimension[1], actualImageDimension[0]);
  } else {
  maxPrimary = maxHeight;
  maxSecondary = 0;
  desiredImageDimension[1] = getResizedDimension(maxPrimary, maxSecondary, actualImageDimension[1], actualImageDimension[0]);
  desiredImageDimension[0] = getResizedDimension(maxPrimary, maxSecondary, actualImageDimension[0], actualImageDimension[1]);
  }
  LogUtils.e("desired width: " + desiredImageDimension[0] + ", desired height: " + desiredImageDimension[1]);
  return desiredImageDimension;
  }
   
  /**
  * 根据显示的最大宽度或最大高度,保持原图的宽高比缩放
  * @param imageResId 图片资源id
  * @param maxWidth 图片显示的最大宽度
  * @param maxHeight 图片显示的最大高度
  * @return
  */
  public static int[] getDesiredImageDimension(Context context, int imageResId, int maxWidth, int maxHeight) {
  int[] desiredImageDimension = new int[2];
  int[] actualImageDimension = getActualImageDimension(context, imageResId);
  LogUtils.e("actual width: " + actualImageDimension[0] + ", actual height: " + actualImageDimension[1]);
  int maxPrimary;
  int maxSecondary;
  if (actualImageDimension[0] >= actualImageDimension[1]) {
  maxPrimary = maxWidth;
  maxSecondary = 0;
  desiredImageDimension[0] = getResizedDimension(maxPrimary, maxSecondary, actualImageDimension[0], actualImageDimension[1]);
  desiredImageDimension[1] = getResizedDimension(maxSecondary, maxPrimary, actualImageDimension[1], actualImageDimension[0]);
  } else {
  maxPrimary = maxHeight;
  maxSecondary = 0;
  desiredImageDimension[1] = getResizedDimension(maxPrimary, maxSecondary, actualImageDimension[1], actualImageDimension[0]);
  desiredImageDimension[0] = getResizedDimension(maxPrimary, maxSecondary, actualImageDimension[0], actualImageDimension[1]);
  }
  LogUtils.e("desired width: " + desiredImageDimension[0] + ", desired height: " + desiredImageDimension[1]);
  return desiredImageDimension;
  }
   
  /**
  * The custom implementation of ImageListener which handles basic functionality
  * of showing a default image until the network response is received, at which point
  * it will switch to either the actual image or the error image.
  * @param view The imageView that the listener is associated with.
  * @param defaultImageResId Default image resource ID to use, or 0 if it doesn't exist.
  * @param errorImageResId Error image resource ID to use, or 0 if it doesn't exist.
  */
  public static ImageLoader.ImageListener getImageListener(final Context context, final ImageView view,
  final int defaultImageResId, final int errorImageResId, int maxWidth, int maxHeight) {
  final int[] desiredImageDimension = VolleyImageUtils.getDesiredImageDimension(context, defaultImageResId, maxWidth, maxHeight);
  return new ImageLoader.ImageListener() {
  @Override
  public void onErrorResponse(VolleyError error) {
  if (errorImageResId != 0) {
  view.setImageBitmap(getScaledBitmap(context, errorImageResId, desiredImageDimension[0], desiredImageDimension[1]));
  }
  }
   
  @Override
  public void onResponse(ImageLoader.ImageContainer response, boolean isImmediate) {
  if (response.getBitmap() != null) {
  view.setImageBitmap(response.getBitmap());
  } else if (defaultImageResId != 0) {
  view.setImageBitmap(getScaledBitmap(context, defaultImageResId, desiredImageDimension[0], desiredImageDimension[1]));
  }
  }
  };
  }
   
  public static void compress(File file, int maxWidth, int maxHeight) {
  FileOutputStream out = null;
  try {
  Bitmap scaledBitmap = getScaledBitmap(file, maxWidth, maxHeight);
  out = new FileOutputStream(file.getAbsolutePath());
   
  // write the compressed bitmap at the destination specified by filename.
  scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 100, out);
   
  } catch (FileNotFoundException e) {
  e.printStackTrace();
  }
  }
   
  }

posted on 2015-06-12 13:56  taoboy  阅读(184)  评论(0)    收藏  举报

导航