package cm.android.util; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import android.annotation.TargetApi; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.graphics.BitmapFactory; import android.graphics.Camera; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.PorterDuff.Mode; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.Shader.TileMode; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.LayerDrawable; import android.view.View; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import cm.java.util.IoUtil; public class BitmapUtil { private static final Logger logger = LoggerFactory.getLogger(BitmapUtil.class); private BitmapUtil() { } /** * 图片旋转 * * @param bmp 要旋转的图片 * @param degree 图片旋转的角度,负值为逆时针旋转,正值为顺时针旋转 */ public static Bitmap rotateBitmap(Bitmap bmp, float degree) { Matrix matrix = new Matrix(); matrix.postRotate(degree); return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); } /** * 图片缩放 * * @param scale 值小于则为缩小,否则为放大 */ public static Bitmap resizeBitmap(Bitmap bm, float scale) { Matrix matrix = new Matrix(); matrix.postScale(scale, scale); return Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } /** * 图片反转 * * @param flag 0为水平反转,1为垂直反转 */ public static Bitmap reverseBitmap(Bitmap bmp, int flag) { float[] floats = null; switch (flag) { case 0: // 水平反转 floats = new float[]{-1f, 0f, 0f, 0f, 1f, 0f, 0f, 0f, 1f}; break; case 1: // 垂直反转 floats = new float[]{1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f}; break; default: break; } if (floats != null) { Matrix matrix = new Matrix(); matrix.setValues(floats); return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true); } return null; } /** * 添加边框 * * @param bm 原图片 * @param res 边框资源 */ public static Bitmap addBigFrame(Context context, Bitmap bm, int res) { Bitmap bitmap = decodeBitmap(context, res); Drawable[] array = new Drawable[2]; array[0] = new BitmapDrawable(bm); Bitmap b = zoomBitmap(bitmap, bm.getWidth(), bm.getHeight()); array[1] = new BitmapDrawable(b); LayerDrawable layer = new LayerDrawable(array); return drawableToBitmap(layer); } /** * 将Drawable转换成Bitmap */ private static Bitmap drawableToBitmap(Drawable drawable) { Bitmap bitmap = Bitmap .createBitmap( drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565); Canvas canvas = new Canvas(bitmap); // canvas.setBitmap(bitmap); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); drawable.draw(canvas); return bitmap; } /** * 图片与边框组合 * * @param bm 原图片 * @param res 边框资源 */ private static Bitmap combinateFrame(Context context, Bitmap bm, int[] res) { Bitmap bmp = decodeBitmap(context, res[0]); // 边框的宽高 final int smallW = bmp.getWidth(); final int smallH = bmp.getHeight(); // 原图片的宽高 final int bigW = bm.getWidth(); final int bigH = bm.getHeight(); int wCount = (int) Math.ceil(bigW * 1.0 / smallW); int hCount = (int) Math.ceil(bigH * 1.0 / smallH); // 组合后图片的宽高 int newW = (wCount + 2) * smallW; int newH = (hCount + 2) * smallH; // 重新定义大小 Bitmap newBitmap = Bitmap.createBitmap(newW, newH, Config.ARGB_8888); Canvas canvas = new Canvas(newBitmap); Paint p = new Paint(); p.setColor(Color.TRANSPARENT); canvas.drawRect(new Rect(0, 0, newW, newH), p); Rect rect = new Rect(smallW, smallH, newW - smallW, newH - smallH); Paint paint = new Paint(); paint.setColor(Color.WHITE); canvas.drawRect(rect, paint); // 绘原图 canvas.drawBitmap(bm, (newW - bigW - 2 * smallW) / 2 + smallW, (newH - bigH - 2 * smallH) / 2 + smallH, null); // 绘边框 // 绘四个角 int startW = newW - smallW; int startH = newH - smallH; Bitmap leftTopBm = decodeBitmap(context, res[0]); // 左上角 Bitmap leftBottomBm = decodeBitmap(context, res[2]); // 左下角 Bitmap rightBottomBm = decodeBitmap(context, res[4]); // 右下角 Bitmap rightTopBm = decodeBitmap(context, res[6]); // 右上角 canvas.drawBitmap(leftTopBm, 0, 0, null); canvas.drawBitmap(leftBottomBm, 0, startH, null); canvas.drawBitmap(rightBottomBm, startW, startH, null); canvas.drawBitmap(rightTopBm, startW, 0, null); leftTopBm.recycle(); leftTopBm = null; leftBottomBm.recycle(); leftBottomBm = null; rightBottomBm.recycle(); rightBottomBm = null; rightTopBm.recycle(); rightTopBm = null; // 绘左右边框 Bitmap leftBm = decodeBitmap(context, res[1]); Bitmap rightBm = decodeBitmap(context, res[5]); for (int i = 0, length = hCount; i < length; i++) { int h = smallH * (i + 1); canvas.drawBitmap(leftBm, 0, h, null); canvas.drawBitmap(rightBm, startW, h, null); } leftBm.recycle(); leftBm = null; rightBm.recycle(); rightBm = null; // 绘上下边框 Bitmap bottomBm = decodeBitmap(context, res[3]); Bitmap topBm = decodeBitmap(context, res[7]); for (int i = 0, length = wCount; i < length; i++) { int w = smallW * (i + 1); canvas.drawBitmap(bottomBm, w, startH, null); canvas.drawBitmap(topBm, w, 0, null); } bottomBm.recycle(); bottomBm = null; topBm.recycle(); topBm = null; canvas.save(Canvas.ALL_SAVE_FLAG); canvas.restore(); return newBitmap; } /** * 将图片内容解析成字节数组 * * @return byte[] */ public static byte[] readStream(InputStream inStream) throws Exception { byte[] buffer = new byte[1024]; int len = -1; ByteArrayOutputStream outStream = new ByteArrayOutputStream(); while ((len = inStream.read(buffer)) != -1) { outStream.write(buffer, 0, len); } byte[] data = outStream.toByteArray(); outStream.close(); inStream.close(); return data; } /** * 将字节数组转换Bitmap * * @return Bitmap */ public static Bitmap getPicFromBytes(byte[] bytes, BitmapFactory.Options opts) { if (bytes != null) { if (opts != null) { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length, opts); } else { return BitmapFactory.decodeByteArray(bytes, 0, bytes.length); } } return null; } /** * 图片缩放 * * @param bitmap 对象 * @param w 要缩放的宽度 * @param h 要缩放的高度 * @return newBmp 新 Bitmap对象 */ public static Bitmap zoomBitmap(Bitmap bitmap, int w, int h) { int width = bitmap.getWidth(); int height = bitmap.getHeight(); Matrix matrix = new Matrix(); float scaleWidth = ((float) w / width); float scaleHeight = ((float) h / height); matrix.postScale(scaleWidth, scaleHeight); Bitmap newBmp = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true); return newBmp; } /** * 把Bitmap转Byte */ public static byte[] bitmapToBytes(Bitmap bm) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.PNG, 100, baos); return baos.toByteArray(); } /** * 根据File返回Bitmap */ public static Bitmap decodeBitmap(File imgFile, int displayWidth, int displayHeight) throws OutOfMemoryError { if (imgFile == null) { return null; } if (!imgFile.isFile()) { return null; } Bitmap bitmap = null; if (displayWidth == 0 || displayHeight == 0) { bitmap = getBitmap(imgFile); } else { // 图片过大进行解码图片 bitmap = decodeBitmap(imgFile.getAbsolutePath(), displayWidth, displayHeight); } return bitmap; } private static Bitmap getBitmap(File imgFile) throws OutOfMemoryError { InputStream is = null; try { // is = new BufferedInputStream(new FileInputStream(path)); // bmp = BitmapFactory.decodeStream(is, null, op); is = new FileInputStream(imgFile); return BitmapFactory.decodeFileDescriptor( ((FileInputStream) is).getFD(), null, null); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } finally { IoUtil.closeQuietly(is); } } /** * 解析图片 */ public static Bitmap decodeBitmap(String path, int displayWidth, int displayHeight) throws OutOfMemoryError { BitmapFactory.Options op = getOptions(path, displayWidth, displayHeight); InputStream is = null; try { // is = new BufferedInputStream(new FileInputStream(path)); // bmp = BitmapFactory.decodeStream(is, null, op); is = new FileInputStream(path); return BitmapFactory.decodeFileDescriptor( ((FileInputStream) is).getFD(), null, op); } catch (IOException e) { e.printStackTrace(); return null; } finally { IoUtil.closeQuietly(is); } } // /** // * 读取Assets资源Drawable/AssetManager // */ // public static Drawable getAssertDrawable(Context context, String path) { // return new BitmapDrawable(readAssetsBitmap(context, path)); // } /** * 读取Assets资源Drawable/AssetManager */ public static Bitmap readAssetsBitmap(Context context, String path, int displayWidth, int displayHeight) throws OutOfMemoryError { Bitmap bitmap = null; InputStream is = null; try { is = context.getAssets().open(path); // bitmap = readBitmap(is); bitmap = decodeBitmap(is, displayWidth, displayHeight); } catch (IOException e) { logger.error("", e); return null; } finally { IoUtil.closeQuietly(is); } return bitmap; } /** * 解析assets目录下文件 */ public static Bitmap readAssetsBitmap(Context context, String path) throws OutOfMemoryError { return readAssetsBitmap(context, path, 0, 0); } /** * 解析图片(待测试) */ public static Bitmap decodeBitmap(InputStream is, int displayWidth, int displayHeight) throws OutOfMemoryError { BitmapFactory.Options op = getOptions(is, displayWidth, displayHeight); return BitmapFactory.decodeStream(is, null, op); } /** * 以最省内存的方式读取本地资源的图片 */ public static Bitmap decodeBitmap(Context context, int resId) throws OutOfMemoryError { InputStream is = context.getResources().openRawResource(resId); try { Bitmap bitmap = readBitmap(is); return bitmap; } catch (OutOfMemoryError e) { throw e; } finally { IoUtil.closeQuietly(is); } } private static Bitmap readBitmap(InputStream is) throws OutOfMemoryError { BitmapFactory.Options opt = new BitmapFactory.Options(); opt.inPreferredConfig = Bitmap.Config.RGB_565; opt.inPurgeable = true; // opt.inJustDecodeBounds = true;// 只描边,不读取数据 opt.inInputShareable = true; // 获取资源图片 Bitmap bitmap = BitmapFactory.decodeStream(is, null, opt); return bitmap; } /** * 获得设置信息 */ public static BitmapFactory.Options getOptions(InputStream is, int displayWidth, int displayHeight) { BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true;// 只读取Bitmap的宽高等信息,不读取像素。 BitmapFactory.decodeStream(is, null, op); // 获取尺寸信息 // 获取比例大小 // Rect r = new Rect(0, 0, displayWidth, displayHeight); // int w = r.width(); // int h = r.height(); // int maxSize = w > h ? w : h; // int inSimpleSize = computeSampleSize(op, UNCONSTRAINED, w * h); if (displayWidth != 0 && displayHeight != 0) { int inSimpleSize = calculateInSampleSize(op, displayWidth, displayHeight); op.inSampleSize = inSimpleSize; // op.inSamplySize 表示的是缩小的比例 // op.inSamplySize = 4,表示缩小1/4的宽和高,1/16的像素,android认为设置为2是最快的。 } // op.outWidth表示的是图像真实的宽度 op.inJustDecodeBounds = false; // 用于节省内存 op.inPreferredConfig = Bitmap.Config.RGB_565; op.inPurgeable = true; op.inInputShareable = true; return op; } /** * 获得设置信息 */ public static BitmapFactory.Options getOptions(String path, int displayWidth, int displayHeight) { BitmapFactory.Options op = new BitmapFactory.Options(); op.inJustDecodeBounds = true;// 只读取Bitmap的宽高等信息,不读取像素。 BitmapFactory.decodeFile(path, op); // 获取尺寸信息 // 获取比例大小 // Rect r = new Rect(0, 0, displayWidth, displayHeight); // int w = r.width(); // int h = r.height(); // int maxSize = w > h ? w : h; // int inSimpleSize = computeSampleSize(op, UNCONSTRAINED, w * h); if (displayWidth != 0 && displayHeight != 0) { int inSimpleSize = calculateInSampleSize(op, displayWidth, displayHeight); op.inSampleSize = inSimpleSize; // op.inSamplySize 表示的是缩小的比例 // op.inSamplySize = 4,表示缩小1/4的宽和高,1/16的像素,android认为设置为2是最快的。 } // op.outWidth表示的是图像真实的宽度 op.inJustDecodeBounds = false; // 用于节省内存 op.inPreferredConfig = Bitmap.Config.RGB_565; op.inPurgeable = true; op.inInputShareable = true; return op; } // /* // * Compute the sample size as a function of minSideLength and // * maxNumOfPixels. minSideLength is used to specify that minimal width or // * height of a bitmap. maxNumOfPixels is used to specify the maximal size // in // * pixels that is tolerable in terms of memory usage. // * // * The function returns a sample size based on the constraints. Both size // * and minSideLength can be passed in as IImage.UNCONSTRAINED, which // * indicates no care of the corresponding constraint. The functions // prefers // * returning a sample size that generates a smaller bitmap, unless // * minSideLength = IImage.UNCONSTRAINED. // * // * Also, the function rounds up the sample size to a power of 2 or // multiple // * of 8 because BitmapFactory only honors sample size this way. For // example, // * BitmapFactory downsamples an image by 2 even though the request is 3. // So // * we round up the sample size to avoid OOM. // */ // public static int computeSampleSize(BitmapFactory.Options options, // int minSideLength, int maxNumOfPixels) { // int initialSize = computeInitialSampleSize(options, minSideLength, // maxNumOfPixels); // // int roundedSize; // if (initialSize <= 8) { // roundedSize = 1; // while (roundedSize < initialSize) { // roundedSize <<= 1; // } // } else { // roundedSize = (initialSize + 7) / 8 * 8; // } // return roundedSize; // } // // public static final int UNCONSTRAINED = -1; // // public static int computeInitialSampleSize(BitmapFactory.Options options, // int minSideLength, int maxNumOfPixels) { // double w = options.outWidth; // double h = options.outHeight; // int lowerBound = (maxNumOfPixels == UNCONSTRAINED) ? 1 : (int) Math // .ceil(Math.sqrt(w * h / maxNumOfPixels)); // int upperBound = (minSideLength == UNCONSTRAINED) ? 128 : (int) Math // .min(Math.floor(w / minSideLength), // Math.floor(h / minSideLength)); // // if (upperBound < lowerBound) { // // return the larger one when there is no overlapping zone. // return lowerBound; // } // if ((maxNumOfPixels == UNCONSTRAINED) // && (minSideLength == UNCONSTRAINED)) { // return 1; // } else if (minSideLength == UNCONSTRAINED) { // return lowerBound; // } else { // return upperBound; // } // } /** * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} * object when decoding bitmaps using the decode* methods from * {@link BitmapFactory}. This implementation calculates the closest * inSampleSize that will result in the final decoded bitmap having a width * and height equal to or larger than the requested width and height. This * implementation does not ensure a power of 2 is returned for inSampleSize * which can be faster when decoding but results in a larger bitmap which * isn't as useful for caching purposes. * * @param options An options object with out* params already populated (run * through a decode* method with inJustDecodeBounds==true * @param reqWidth The requested width of the resulting bitmap * @param reqHeight The requested height of the resulting bitmap * @return The value to be used for inSampleSize */ public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int width = options.outWidth; final int height = options.outHeight; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and // width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will // guarantee a final image // with both dimensions larger than or equal to the requested height // and width. // TODO 2013-07-25 ggg,在参数宽高比例与原图不一致的情况下,按最小的那个比例缩放 inSampleSize = heightRatio > widthRatio ? heightRatio : widthRatio; // This offers some additional logic in case the image has a strange // aspect ratio. For example, a panorama may have a much larger // width than height. In these cases the total pixels might still // end up being too large to fit comfortably in memory, so we should // be more aggressive with sample down the image (=larger // inSampleSize). final float totalPixels = width * height; // Anything more than 2x the requested pixels we'll sample down // further final float totalReqPixelsCap = reqWidth * reqHeight * 2; while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) { inSampleSize++; } } return inSampleSize; } /** * 创建带有倒影效果的bitmap(canvas中直接画上原bitmap和倒影图片) * * @param reflectionHeight 倒影高 * @param reflectionGap 原图与倒影之间的间距 */ public static Bitmap createBitmapWithReflection2(Bitmap srcBitmap, int reflectionHeight, int reflectionGap) { // 原始宽高 int srcWidth = srcBitmap.getWidth(); int srcHeight = srcBitmap.getHeight(); // 倒影高 // int reflectionHeight = srcHeight / 4; // 创建倒影图片,图片反转+渐变 Bitmap reflectionBitmap = createReflectionBitmapWithGradient(srcBitmap, reflectionHeight); // 倒影与原图的间隔 final int REFLECTION_GAP = reflectionGap; // 最终的bitmap Bitmap finalBitmapWithReflection = Bitmap.createBitmap(srcWidth, srcHeight + reflectionHeight + REFLECTION_GAP, Bitmap.Config.ARGB_8888); // finalBitmapWithReflection.eraseColor(Color.TRANSPARENT); // Prepare the canvas to draw stuff. Canvas canvas = new Canvas(finalBitmapWithReflection); // Draw the original bitmap. canvas.drawBitmap(srcBitmap, 0, 0, null); // Draw the reflection bitmap. canvas.drawBitmap(reflectionBitmap, 0, srcHeight + REFLECTION_GAP, null); return finalBitmapWithReflection; } /** * 创建带有渐变效果的bitmap(canva中先画好原bitmap和反转bitmap后再处理渐变),推荐使用 */ public static Bitmap createBitmapWithReflection(Bitmap srcBitmap, int reflectionHeight, int reflectionGap) { // 原始宽高 int srcWidth = srcBitmap.getWidth(); int srcHeight = srcBitmap.getHeight(); // 倒影高 // int reflectionHeight = srcHeight / 4; // 创建倒影图片,图片反转+渐变 Bitmap reflectionBitmap = createReflectionBitmap(srcBitmap, reflectionHeight); // 倒影与原图的间隔 final int REFLECTION_GAP = reflectionGap; // 最终的bitmap Bitmap finalBitmapWithReflection = Bitmap.createBitmap(srcWidth, srcHeight + reflectionHeight + REFLECTION_GAP, Bitmap.Config.ARGB_8888); // finalBitmapWithReflection.eraseColor(Color.TRANSPARENT); // Prepare the canvas to draw stuff. Canvas canvas = new Canvas(finalBitmapWithReflection); // Draw the original bitmap. canvas.drawBitmap(srcBitmap, 0, 0, null); // Draw the reflection bitmap. canvas.drawBitmap(reflectionBitmap, 0, srcHeight + REFLECTION_GAP, null); // 渐变在最后实现 processLinearGradient(canvas, srcHeight + reflectionGap, srcWidth, finalBitmapWithReflection.getHeight()); return finalBitmapWithReflection; } /** * 创建倒影+渐变图片 * * @param reflectionHeight 倒影高 */ public static Bitmap createReflectionBitmapWithGradient(Bitmap srcBitmap, int reflectionHeight) { Bitmap reflectionBitmap = createReflectionBitmap(srcBitmap, reflectionHeight); return createLinearGradient(reflectionBitmap); } /** * 创建倒影图片(无渐变) */ public static Bitmap createReflectionBitmap(Bitmap srcBitmap, int reflectionHeight) { // 原始宽高 int srcWidth = srcBitmap.getWidth(); int srcHeight = srcBitmap.getHeight(); // 倒影高 // int reflectionHeight = srcHeight / 4; // 实现图片反转 Matrix matrix = new Matrix(); // 1表示放大比例,不放大也不缩小。 -1表示在y轴上相反,即旋转180度。 matrix.preScale(1, -1); // 创建反转后的图片Bitmap对象 Bitmap reflectionBitmap = Bitmap.createBitmap(srcBitmap, 0, srcHeight - reflectionHeight, srcWidth, reflectionHeight, matrix, false); return reflectionBitmap; } /** * 创建渐变图像 */ public static Bitmap createLinearGradient(Bitmap srcBitmap) { Bitmap finalBitmap = Bitmap.createBitmap(srcBitmap.getWidth(), srcBitmap.getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(finalBitmap); canvas.drawBitmap(srcBitmap, 0, 0, null); processLinearGradient(canvas, 0, srcBitmap.getWidth(), srcBitmap.getHeight()); return finalBitmap; } /** * 竖直方向渐变 */ public static void processLinearGradient(Canvas canvas, float top, float width, float bottom) { /** * 渐变<br> * 参数一:为渐变起点坐标的x轴位置.<br> * 参数二 :为渐变起点坐标的y轴位置. <br> * 参数三:为渐变终点坐标的x轴位置,<br> * 参数四:为渐变终点坐标的y轴位置,<br> */ // LinearGradient shader = new LinearGradient(0, 0, 0, // reflectionBitmap.getHeight(), 0x70FFFFFF, 0x00FFFFFF, // TileMode.CLAMP); LinearGradient shader = new LinearGradient(0, top, 0, bottom, 0x70FFFFFF, 0x00FFFFFF, TileMode.CLAMP); Paint paint = new Paint(); paint.setAntiAlias(true); paint.setShader(shader); // Set the Transfer mode to be porter duff and destination in paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN)); // Draw the linear shader. canvas.drawRect(0, top, width, bottom, paint); } /** * 创建沿Y轴旋转的bitmap */ public static Bitmap createRotateBitmap(Bitmap srcBitmap, float angle) { // 旋转角度 // double angleRadians = Math.toRadians(angle); // int width = (int) (Math.cos(angleRadians) * srcBitmap.getWidth()); Matrix matrix = new Matrix(); // // 对称轴翻转 Camera camera = new Camera(); camera.save(); // rotate // camera.rotateX(angle); camera.rotateY(angle); // camera.rotateZ(rotateZ); // translate // camera.translate(0, 0, translateZ); camera.getMatrix(matrix); // 恢复到之前的初始状态。 camera.restore(); // 设置图像处理的中心点 matrix.preTranslate(srcBitmap.getWidth() >> 1, srcBitmap.getHeight() >> 1); matrix.preSkew(0f, 0.1f); // matrix.postSkew(skewX, skewY); // 直接setSkew(),则前面处理的rotate()、translate()等等都将无效。 Bitmap bitmap = Bitmap.createBitmap(srcBitmap, 0, 0, srcBitmap.getWidth(), srcBitmap.getHeight(), matrix, true); return bitmap; } /** * 从view 得到图片 */ @TargetApi(4) public static Bitmap getBitmapFromView(View view) { view.destroyDrawingCache(); view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec .makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)); view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); view.setDrawingCacheEnabled(true); Bitmap bitmap = view.getDrawingCache(true); return bitmap; // int spec = View.MeasureSpec.makeMeasureSpec(0, // View.MeasureSpec.UNSPECIFIED); // view.measure(spec, spec); // view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); // Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), // Bitmap.Config.ARGB_8888); // Canvas canvas = new Canvas(bitmap); // view.draw(canvas); // return b; } }