/* * Copyright 2015 Hippo Seven * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.hippo.nimingban.util; import android.app.ActivityManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.support.annotation.NonNull; import com.hippo.yorozuya.MathUtils; import com.hippo.yorozuya.io.InputStreamPipe; import java.io.IOException; public class BitmapUtils { public static Context sContext; public static void initialize(Context context) { sContext = context.getApplicationContext(); } public static long availableMemory() { final Runtime runtime = Runtime.getRuntime(); final long used = runtime.totalMemory() - runtime.freeMemory(); final ActivityManager activityManager = (ActivityManager) sContext. getSystemService(Context.ACTIVITY_SERVICE); final long total = activityManager.getMemoryClass() * 1024 * 1024; return total - used; } public static Bitmap decodeStream(@NonNull InputStreamPipe isp, int maxWidth, int maxHeight, int pixels, boolean checkMemory, boolean justCalc, int[] sampleSize) { try { isp.obtain(); BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(isp.open(), null, options); isp.close(); int width = options.outWidth; int height = options.outHeight; if (width <= 0 || height <= 0) { if (sampleSize != null && sampleSize.length >= 1) { sampleSize[0] = -1; } return null; } int scaleW = 1; int scaleH = 1; int scaleP = 1; int scaleM = 1; if (maxWidth > 0 && width > maxWidth) { scaleW = MathUtils.ceilDivide(width, maxWidth); } if (maxHeight > 0 && height > maxHeight) { scaleH = MathUtils.ceilDivide(height, maxHeight); } if (pixels > 0 && width * height > pixels) { scaleP = (int) Math.ceil(Math.sqrt(width * height / (float) pixels)); } if (checkMemory) { long m = availableMemory() - 5 * 1024 * 1024; // Leave 5m if (m < 0) { if (sampleSize != null && sampleSize.length >= 1) { sampleSize[0] = -1; } return null; } if (width * height * 3 > m) { scaleM = (int) Math.ceil(Math.sqrt(width * height * 3 / (float) m)); } } options.inSampleSize = MathUtils.nextPowerOf2(MathUtils.max(scaleW, scaleH, scaleP, scaleM, 1)); if (sampleSize != null && sampleSize.length >= 1) { sampleSize[0] = options.inSampleSize; } options.inJustDecodeBounds = false; if (justCalc) { return null; } else { try { return BitmapFactory.decodeStream(isp.open(), null, options); } catch (OutOfMemoryError e) { if (sampleSize != null && sampleSize.length >= 1) { sampleSize[0] = -1; } return null; } } } catch (IOException e) { if (sampleSize != null && sampleSize.length >= 1) { sampleSize[0] = -1; } return null; } finally { isp.close(); isp.release(); } } /** * @return null or the bitmap */ public static Bitmap decodeStream(@NonNull InputStreamPipe isp, int maxWidth, int maxHeight) { return decodeStream(isp, maxWidth, maxHeight, -1, false, false, null); } }