BitmapUtil 很多有用的方法

/**
 *
 * Copyright (c) 2014 CoderKiss
 *
 * CoderKiss[AT]gmail.com
 *
 */

package com.kisstools.utils;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.media.ExifInterface;
import android.media.ThumbnailUtils;
import android.os.Build;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.provider.MediaStore.Images;
import android.text.TextUtils;
import android.view.Gravity;

public class BitmapUtil {
   public static final String TAG = "BitmapUtil";

   public static ImageSize getImageSize(String absPath) {
      if (TextUtils.isEmpty(absPath)) {
         return null;
      }
      Options options = getOptions(absPath);
      int width = options.outWidth;
      int height = options.outHeight;
      ImageSize size = new ImageSize(width, height);
      return size;
   }

   @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
   public static int getImageBytes(Bitmap bitmap) {
      if (bitmap == null) {
         return 0;
      }
      int bitmapSize = 0;
      if (VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1) {
         bitmapSize = bitmap.getByteCount();
      } else {
         bitmapSize = bitmap.getRowBytes() * bitmap.getHeight();
      }
      if (bitmapSize < 0) {
         bitmapSize = 0;
      }

      return bitmapSize;
   }

   public static Options getOptions(String absPath) {
      if (TextUtils.isEmpty(absPath)) {
         return null;
      }
      Options options = new Options();
      options.inPreferredConfig = Config.ALPHA_8;
      options.inJustDecodeBounds = true;
      BitmapFactory.decodeFile(absPath, options);
      return options;
   }

   public static Options getOptions(String absPath, int desireWidth,
         int desireHeight) {
      if (!FileUtil.exists(absPath) || desireWidth <= 0 || desireHeight <= 0) {
         return null;
      }
      Options options = getOptions(absPath);
      int scaleW = sampleSize(options.outWidth, desireWidth);
      int scaleH = sampleSize(options.outHeight, desireWidth);
      options.inSampleSize = scaleH > scaleW ? scaleH : scaleW;
      options.inJustDecodeBounds = false;
      return options;
   }

   public static Bitmap getAssetBitmap(Context context, String filePath) {
      AssetManager assetManager = context.getAssets();
      InputStream ips = null;
      Bitmap bitmap = null;
      try {
         ips = assetManager.open(filePath);
         bitmap = BitmapFactory.decodeStream(ips);
      } catch (IOException e) {
         e.printStackTrace();
      }
      return bitmap;
   }

   public static Bitmap getImage(String absPath) {
      if (!FileUtil.exists(absPath)) {
         LogUtil.w(TAG, "invalid file path: " + absPath);
         return null;
      }

      LogUtil.d(TAG, "decode bitmap " + absPath);
      long enter = System.currentTimeMillis();
      Bitmap bitmap = BitmapFactory.decodeFile(absPath);
      long delta = System.currentTimeMillis() - enter;
      LogUtil.v(TAG, "decode bitmap time " + delta);

      return bitmap;
   }

   public static Bitmap getImage(String absPath, ImageSize size) {
      if (TextUtils.isEmpty(absPath)) {
         return null;
      }

      if (ImageSize.valid(size)) {
         return getImage(absPath, size.getWidth(), size.getHeight());
      } else {
         return getImage(absPath);
      }
   }

   public static Bitmap getImage(String absPath, int width, int height) {
      if (width <= 0 && height <= 0 || !FileUtil.exists(absPath)) {
         LogUtil.e(TAG, "invalid parameters absPath " + absPath + " width "
               + width + " height " + height);
         return null;
      }

      LogUtil.d(TAG, "decode bitmap " + absPath + " width " + width
            + " height " + height);
      long enter = System.currentTimeMillis();
      Options options = getOptions(absPath, width, height);
      Bitmap bitmap = BitmapFactory.decodeFile(absPath, options);
      if (bitmap == null) {
         LogUtil.i(TAG, "decode bitmap failed " + absPath);
         return null;
      }

      int rotate = getRotate(absPath);
      bitmap = rotateImage(bitmap, rotate);
      System.gc();
      long delta = System.currentTimeMillis() - enter;
      LogUtil.v(TAG, "decode bitmap time " + delta);
      return bitmap;
   }

   public static Bitmap rotateImage(Bitmap bitmap, int rotate) {
      if (bitmap == null) {
         return bitmap;
      }
      Matrix matrix = new Matrix();
      matrix.setRotate(rotate);
      Bitmap rotated = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),
            bitmap.getHeight(), matrix, true);
      if (rotated != null && !rotated.equals(bitmap)) {
         bitmap.recycle();
         bitmap = rotated;
      }
      return bitmap;
   }

   public static boolean saveImage(Bitmap bitmap, String absPath) {
      return saveImage(bitmap, absPath, 100);
   }

   public static boolean saveImage(Bitmap bitmap, String absPath, int quality) {
      if (!FileUtil.create(absPath)) {
         LogUtil.w(TAG, "create file failed.");
         return false;
      }

      try {
         File outFile = new File(absPath);
         FileOutputStream fos = new FileOutputStream(outFile);
         BufferedOutputStream bos = new BufferedOutputStream(fos);
         bitmap.compress(Bitmap.CompressFormat.PNG, quality, bos);
         bos.flush();
         bos.close();
      } catch (IOException e) {
         e.printStackTrace();
         LogUtil.e(TAG, "failed to write image content");
         return false;
      }

      return true;
   }

   public static Bitmap squareImage(Bitmap bitmap) {
      if (bitmap == null) {
         return null;
      }
      int width = bitmap.getWidth();
      int height = bitmap.getHeight();
      if (width == height) {
         LogUtil.w(TAG, "no need to square image");
         return bitmap;
      }
      int x = (height < width) ? ((width - height) / 2) : 0;
      int y = (width < height) ? ((height - width) / 2) : 0;
      int pixels = width < height ? width : height;
      Bitmap square = Bitmap.createBitmap(bitmap, x, y, pixels, pixels);
      return square;
   }

   public static int getRotate(String absPath) {
      if (!FileUtil.exists(absPath)) {
         LogUtil.w(TAG, "invalid file path");
         return 0;
      }

      ExifInterface exifInterface = null;
      try {
         exifInterface = new ExifInterface(absPath);
      } catch (IOException e) {
         e.printStackTrace();
         return 0;
      }

      int orientation = exifInterface.getAttributeInt(
            ExifInterface.TAG_ORIENTATION,
            ExifInterface.ORIENTATION_UNDEFINED);
      int rotate = 0;
      switch (orientation) {
      case ExifInterface.ORIENTATION_ROTATE_90:
         rotate = 90;
         break;
      case ExifInterface.ORIENTATION_ROTATE_180:
         rotate = 180;
         break;
      case ExifInterface.ORIENTATION_ROTATE_270:
         rotate = 270;
         break;
      default:
         break;
      }
      LogUtil.v(TAG, "image rotate " + rotate);
      return rotate;
   }

   public static Bitmap resizeImage(Bitmap bitmap, int desireWidth,
         int desireHeight, boolean isEnlarge) {
      if (bitmap == null || desireHeight <= 0 || desireWidth <= 0) {
         return null;
      }

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

      if (width <= 0 || height <= 0) {
         return bitmap;
      }
      if (!isEnlarge && (width < desireWidth && height < desireHeight)) {
         return bitmap;
      }
      float scale;
      if (width < height) {
         scale = (float) desireHeight / (float) height;
         if (desireWidth < width * scale) {
            scale = (float) desireWidth / (float) width;
         }
      } else {
         scale = (float) desireWidth / (float) width;
      }

      Matrix matrix = new Matrix();
      matrix.postScale(scale, scale);
      bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);

      return bitmap;
   }

   public final static Bitmap getThumbnail(String absPath, int width,
         int height) {
      if (!FileUtil.exists(absPath) || width <= 0 || height <= 0) {
         return null;
      }
      Options options = getOptions(absPath, width, height);
      try {
         Bitmap bitmap = BitmapFactory.decodeFile(absPath, options);
         Bitmap result = ThumbnailUtils.extractThumbnail(bitmap, width,
               height, ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
         // recycle(bitmap);
         return result;
      } catch (Exception e) {
         e.printStackTrace();
      } catch (OutOfMemoryError e) {
         e.printStackTrace();
      }
      return null;
   }

   public final static Bitmap getVideoThumbnail(String absPath, int width,
         int height) {
      if (!FileUtil.exists(absPath) || width <= 0 || height <= 0) {
         return null;
      }
      Bitmap bitmap = null;
      bitmap = ThumbnailUtils.createVideoThumbnail(absPath,
            Images.Thumbnails.MINI_KIND);
      LogUtil.d(TAG, "bitmap width " + bitmap.getWidth() + " height "
            + bitmap.getHeight());
      bitmap = ThumbnailUtils.extractThumbnail(bitmap, width, height,
            ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
      return bitmap;
   }

   public final static Bitmap waterMark(Context context, Bitmap bitmap,
         int waterResId, int gravity) {
      Drawable waterPrintDrawable = context.getResources().getDrawable(
            waterResId);
      int waterPrintWidth = waterPrintDrawable.getIntrinsicWidth();
      int waterPrintHeight = waterPrintDrawable.getIntrinsicHeight();
      int w = bitmap.getWidth();
      int h = bitmap.getHeight();
      if (gravity == Gravity.CENTER) {
         waterPrintDrawable.setBounds((w - waterPrintWidth) / 2,
               (h - waterPrintHeight) / 2, (w + waterPrintWidth) / 2,
               (h + waterPrintHeight) / 2);
      } else {
         waterPrintDrawable.setBounds((w - waterPrintWidth) / 2, h,
               (w + waterPrintWidth) / 2, h + waterPrintHeight);
      }
      Canvas mCanvas = new Canvas(bitmap);
      waterPrintDrawable.draw(mCanvas);
      return bitmap;
   }

   public final static Bitmap toRounded(Context context, Bitmap bitmap,
         int color, int borderDips, int desireWidth) {
      try {
         Bitmap bitmap0 = squareImage(bitmap);
         Bitmap bitmap1 = resizeImage(bitmap0, desireWidth, desireWidth,
               true);
         int toPX = DeviceUtil.dp2px(borderDips);
         int maxBorder = (desireWidth / 2) / 5;
         maxBorder = maxBorder > 15 ? 15 : maxBorder;
         final int borderSizePx = toPX > maxBorder ? maxBorder : toPX;

         final int size = desireWidth;
         int center = (int) (size / 2);
         int left = (int) ((desireWidth - size) / 2);
         int top = (int) ((desireWidth - size) / 2);
         int right = left + size;
         int bottom = top + size;

         Bitmap output = Bitmap.createBitmap(size, size, Config.ARGB_8888);
         Canvas canvas = new Canvas(output);
         final Paint paint = new Paint();

         final Rect src = new Rect(left, top, right, bottom);
         final Rect dst = new Rect(0, 0, size, size);

         canvas.drawARGB(0, 0, 0, 0);
         // draw border
         paint.setColor(Color.WHITE);
         paint.setAntiAlias(true);
         int radius = center - borderSizePx;
         canvas.drawCircle(center, center, radius, paint);
         // draw bitmap
         paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
         canvas.drawBitmap(bitmap1, src, dst, paint);
         paint.setXfermode(null);

         paint.setStyle(Paint.Style.STROKE);
         paint.setStrokeWidth((float) borderSizePx);
         radius = center - borderSizePx / 2;
         canvas.drawCircle(center, center, radius, paint);
         canvas.save();
         recycle(bitmap0, bitmap1, bitmap);
         return output;
      } catch (Exception e) {
         e.printStackTrace();
      }
      return bitmap;
   }

   public static Bitmap toRoundCorner(Context context, Bitmap bitmap) {
      try {
         int w = bitmap.getWidth();
         int h = bitmap.getHeight();
         final int delta = DeviceUtil.dp2px(5);
         final float roundPx = DeviceUtil.dp2px(14);
         final Paint paint = new Paint();
         paint.setAntiAlias(true);

         /* draw round foreground */
         int foreW = w - 2 * delta;
         int foreH = h - 2 * delta;
         Bitmap foreBmp = Bitmap
               .createBitmap(foreW, foreH, Config.ARGB_8888);
         Rect rect = new Rect(0, 0, foreW, foreH);
         RectF rectF = new RectF(rect);
         Canvas canvas0 = new Canvas(foreBmp);
         canvas0.drawRoundRect(rectF, roundPx, roundPx, paint);
         paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
         canvas0.drawBitmap(bitmap, null, rect, paint);

         /* draw round background */
         Drawable drawable = getDrawbale(0xffffffff, (int) (delta + roundPx));
         drawable.setBounds(0, 0, w, h);
         Bitmap result = Bitmap.createBitmap(w, h, Config.ARGB_8888);
         Canvas canvas = new Canvas(result);
         drawable.draw(canvas);
         canvas.drawBitmap(foreBmp, delta, delta, null);
         recycle(foreBmp, bitmap);

         return result;
      } catch (Exception e) {
         e.printStackTrace();
         return bitmap;
      }
   }

   public final static GradientDrawable getDrawbale(int argb, int radius) {
      GradientDrawable drawable = new GradientDrawable();
      drawable.setCornerRadius(radius);
      drawable.setColor(argb);
      return drawable;
   }

   public final static Bitmap drawRing(Bitmap bitmap, int deltaRadius,
         int color) {
      int w = bitmap.getWidth();
      int dia = deltaRadius * 2 + w;
      float radius = (float) dia / 2;
      Bitmap resultBitmap = Bitmap.createBitmap(dia, dia, Config.ARGB_8888);
      Paint paint = new Paint();
      paint.setColor(color);
      paint.setAlpha(128);
      paint.setAntiAlias(true);
      Canvas canvas = new Canvas(resultBitmap);
      canvas.drawCircle(radius, radius, radius, paint);
      canvas.drawBitmap(bitmap, deltaRadius, deltaRadius, null);
      return resultBitmap;
   }

   public final static Bitmap getRound(int argb, int dia) {
      float radius = dia / 2;
      Bitmap resultBitmap = Bitmap.createBitmap(dia, dia, Config.ARGB_8888);
      Paint paint = new Paint();
      paint.setColor(argb);
      paint.setAntiAlias(true);
      Canvas canvas = new Canvas(resultBitmap);
      canvas.drawCircle(radius, radius, radius, paint);
      return resultBitmap;
   }

   public final static Bitmap stretch(Bitmap bitmap, int height) {
      if (bitmap == null) {
         return null;
      }
      if (height <= bitmap.getHeight()) {
         return bitmap;
      }
      int w = bitmap.getWidth();
      int h = bitmap.getHeight();
      int tmpHeight = 1;
      Bitmap resultBitmap = Bitmap.createBitmap(w, height, Config.ARGB_8888);
      Canvas mCanvas = new Canvas(resultBitmap);
      mCanvas.drawBitmap(bitmap, 0, 0, null);
      Bitmap tmp = Bitmap
            .createBitmap(bitmap, 0, h - tmpHeight, w, tmpHeight);
      bitmap.recycle();
      for (int index = 0; index < (height - h) / tmpHeight; index++) {
         mCanvas.drawBitmap(tmp, 0, h + index * tmpHeight, null);
      }
      tmp.recycle();
      return resultBitmap;
   }

   public static Bitmap overlay(final Bitmap bitmap) {
      if (bitmap == null) {
         return null;
      }
      int width = bitmap.getWidth();
      int height = bitmap.getHeight();
      if (width == 0 || height == 0) {
         return null;
      }
      float rota = 345;
      double radians = Math.toRadians(rota);
      /* after rotate , the new width is the original width */
      int rotateWidth = (int) (width / (Math.abs(Math.sin(radians)) + Math
            .abs(Math.cos(radians))));
      int delta = (width - rotateWidth) / 2;

      // result
      Bitmap result = Bitmap.createBitmap(width, width, Config.ARGB_8888);
      Canvas canvas = new Canvas(result);
      // foreground
      Bitmap foreBmp = resizeImage(bitmap, rotateWidth, rotateWidth, true);
      // rotate
      Matrix matrix = new Matrix();
      matrix.postRotate(rota);
      Bitmap rotate = Bitmap.createBitmap(foreBmp, 0, 0, rotateWidth,
            rotateWidth, matrix, true);
      canvas.drawBitmap(rotate, 0, 0, null);
      canvas.drawBitmap(foreBmp, delta, delta, null);
      recycle(bitmap, rotate, foreBmp);
      return result;
   }

   public static Bitmap drawLayoutDropShadow(Bitmap bitmap) {
      BlurMaskFilter blurFilter = new BlurMaskFilter(2,
            BlurMaskFilter.Blur.OUTER);
      Paint shadowPaint = new Paint();
      shadowPaint.setMaskFilter(blurFilter);
      int[] offsetXY = { 5, 5 };
      Bitmap shadowBitmap = bitmap.extractAlpha(shadowPaint, offsetXY);
      Bitmap shadowImage32 = shadowBitmap.copy(Bitmap.Config.ARGB_8888, true);
      Canvas c = new Canvas(shadowImage32);
      c.drawBitmap(bitmap, 0, 0, null);
      return shadowImage32;
   }

   public static Bitmap blur(Bitmap origin, int radius) {
      int iterations = 1;
      int width = origin.getWidth();
      int height = origin.getHeight();
      int[] inPixels = new int[width * height];
      int[] outPixels = new int[width * height];
      Bitmap bitmap = Bitmap.createBitmap(width, height,
            Bitmap.Config.ARGB_8888);
      origin.getPixels(inPixels, 0, width, 0, 0, width, height);
      for (int index = 0; index < iterations; index++) {
         blur(inPixels, outPixels, width, height, radius);
         blur(outPixels, inPixels, height, width, radius);
      }
      bitmap.setPixels(inPixels, 0, width, 0, 0, width, height);
      return bitmap;
   }

   private static void blur(int[] in, int[] out, int width, int height,
         int radius) {
      int widthMinus1 = width - 1;
      int tableSize = 2 * radius + 1;
      int divide[] = new int[256 * tableSize];

      for (int index = 0; index < 256 * tableSize; index++) {
         divide[index] = index / tableSize;
      }

      int inIndex = 0;

      for (int y = 0; y < height; y++) {
         int outIndex = y;
         int ta = 0, tr = 0, tg = 0, tb = 0;

         for (int i = -radius; i <= radius; i++) {
            int rgb = in[inIndex + clamp(i, 0, width - 1)];
            ta += (rgb >> 24) & 0xff;
            tr += (rgb >> 16) & 0xff;
            tg += (rgb >> 8) & 0xff;
            tb += rgb & 0xff;
         }

         for (int x = 0; x < width; x++) {
            out[outIndex] = (divide[ta] << 24) | (divide[tr] << 16)
                  | (divide[tg] << 8) | divide[tb];

            int i1 = x + radius + 1;
            if (i1 > widthMinus1)
               i1 = widthMinus1;
            int i2 = x - radius;
            if (i2 < 0)
               i2 = 0;
            int rgb1 = in[inIndex + i1];
            int rgb2 = in[inIndex + i2];

            ta += ((rgb1 >> 24) & 0xff) - ((rgb2 >> 24) & 0xff);
            tr += ((rgb1 & 0xff0000) - (rgb2 & 0xff0000)) >> 16;
            tg += ((rgb1 & 0xff00) - (rgb2 & 0xff00)) >> 8;
            tb += (rgb1 & 0xff) - (rgb2 & 0xff);
            outIndex += height;
         }
         inIndex += width;
      }
   }

   private static int clamp(int x, int a, int b) {
      return (x < a) ? a : (x > b) ? b : x;
   }

   private static int sampleSize(int size, int target) {
      int sample = 1;
      for (int index = 0; index < 10; index++) {
         if (size < target * 2) {
            break;
         }
         size = size / 2;
         sample = sample * 2;
      }
      return sample;
   }

   private final static void recycle(Bitmap... bitmaps) {
      if (bitmaps == null || bitmaps.length == 0) {
         return;
      }
      for (Bitmap bitmap : bitmaps) {
         if (bitmap == null) {
            continue;
         }
         if (!bitmap.isRecycled()) {
            bitmap.recycle();
            continue;
         }
         bitmap = null;
      }
      System.gc();
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值