Android 圖片加載經常出現內存OOM異常,處理起來也很複雜,主要是圖片分辨率過大(如:2880*1620),但是基本原理大概如下:
public static Bitmap oomSolution(Resources res,int resID,int widthpx,int heightpx){
Options options =new BitmapFactory.Options();
options.inJustDecodeBounds=true;//不在內存中讀取圖片
options.inPreferredConfig = Bitmap.Config.RGB_565;//代表RGB位圖
BitmapFactory.decodeResource(res,resID, options);//壓縮前圖片
int width= options.outWidth;//原始圖片寬
int height=options.outHeight;//原始圖片高
if(height>heightpx||width>widthpx){
int inheight=Math.round((float)height/(float)heightpx);
int inwidth=Math.round((float)width/(float)widthpx);
int inSize=inheight>inwidth?inheight:inwidth;
options.inSampleSize=inSize;//縮放值:1不縮放 2爲縮放1/2
}
options.inJustDecodeBounds=false;//在內存中創建圖片
Bitmap bm = BitmapFactory.decodeResource(res,resID, options);//壓縮後的圖片
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,20, baos);//壓縮圖片
return bm;
}
來源:http://blog.csdn.net/a704755096/article/details/49912211
附:Bitmap圖片轉換工具
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Matrix;
import android.graphics.Shader;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
public class BitmapUtils {
/**
*Bitmap to Drawable
* @param bmp
* @return Drawable
*/
public static Drawable getBitmapDrawable(Bitmap bmp) {
BitmapDrawable bd = new BitmapDrawable(bmp);
return bd;
}
/**
* Drawable to Bitmap
* @param drawable
* @return Bitmap
*/
public static Bitmap getDrawableBitmap(Drawable drawable) {
BitmapDrawable bd = (BitmapDrawable) drawable;
Bitmap bm = bd.getBitmap();
return bm;
}
/**資源圖片Resources to Bitmap
* @param activity
* @param resId
* @return Bitmap
*/
public static Bitmap getResourcesBitmap(Activity activity, int resId) {
Resources res = activity.getResources();
return BitmapFactory.decodeResource(res, resId);
}
/**數組轉圖片byte[] to Bitmap
* @param bytee
* @return Bitmap
*/
public static Bitmap getBytesBimap(byte[] bytee) {
if (bytee.length == 0) {
return null;
}
return BitmapFactory.decodeByteArray(bytee, 0,bytee.length);
}
/**圖片轉數組Bitmap to byte[]
* @param bm
* @return byte[]
*/
public static byte[] getBitmapBytes(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG,20, baos);
return baos.toByteArray();
}
/**放大圖片
* @param bitmap
* @return Bitmap
*/
public static Bitmap getBigBitmap(Bitmap bitmap) {
Matrix matrix = new Matrix();
matrix.postScale(1.5f,1.5f); //長和寬放大縮小的比例
Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
return resizeBmp;
}
/**縮小圖片
* @param bitmap
* @return Bitmap
*/
public static Bitmap getSmallBitmap(Bitmap bitmap) {
Matrix matrix = new Matrix();
matrix.postScale(0.4f ,0.4f); //長和寬放大縮小的比例
Bitmap resizeBmp = Bitmap.createBitmap(bitmap,0,0,bitmap.getWidth(),bitmap.getHeight(),matrix,true);
return resizeBmp;
}
/**圓形圖片
* @param source
* @return Bitmap
*/
public static Bitmap getCircleImage(Bitmap source) {
int length = source.getWidth() < source.getHeight() ? source.getWidth() : source.getHeight();
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source,Shader.TileMode.CLAMP,Shader.TileMode.CLAMP));//遮罩
Bitmap bmp = Bitmap.createBitmap(length,length,source.getConfig());
Canvas canvas = new Canvas(bmp);
canvas.drawCircle(length / 2, length / 2, length / 2, paint);
return bmp;
}
/**線程獲取url圖片url to Bitmap
* @param img imageview
* @param urlstr url地址
* @param isCircular true圓形,false不變
*/
public static void getUrlBitmap(final ImageView img,final String urlstr,final boolean isCircular){
if(urlstr==null||urlstr.trim().length()==0){
return;
}
new Thread(){
@Override
public void run() {
super.run();
try {
URL url = new URL(urlstr);
URLConnection conn = url.openConnection();
conn.connect();
InputStream in = conn.getInputStream();
final Bitmap map = BitmapFactory.decodeStream(in);
in.close();
img.post(new Runnable() {
@Override
public void run() {
if(isCircular) {
img.setImageBitmap(getCircleImage(map));
}else{
img.setImageBitmap(map);
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
/**截屏Screenshot(view轉Bitmap)加背景框http://blog.csdn.net/yanzi1225627/article/details/8622257
* @param view 當前視圖截屏getWindow().getDecorView()
* @return Bitmap
*/
public static Bitmap getScreenshotBitmap(View view){
//當前視圖截屏view=getWindow().getDecorView()
int viewWidth = view.getMeasuredWidth();
int viewHeight = view.getMeasuredHeight();
Bitmap bitmap=null;
if (viewWidth > 0 && viewHeight > 0) {
bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Config.RGB_565);
Canvas cvs = new Canvas(bitmap);
//cvs.drawColor(view.getDrawingCacheBackgroundColor());
view.draw(cvs);
// MediaStore.Images.Media.insertImage(getContentResolver(),bitmap,"title","description");//保存下載到相冊-返回uriString
// sendBroadcast(new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,Uri.fromFile(new File(getPath(uriString)))));//刷新相冊-getPath函數uriString轉路徑(禁用)
return bitmap;
}
// MediaMetadataRetriever retriever = new MediaMetadataRetriever();//本地視頻截圖
// retriever.setDataSource(filePath);
// String timeString = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
// retriever.getFrameAtTime(Long.parseLong(timeString) * 1000);
return bitmap;
}
/**文件圖片解決OOM(file to Bitmap)
* @param filepath SD卡本地路徑注意版本兼容
* @return Bitmap
*/
public static Bitmap getOOMBitmap(String filepath){
Options options =new BitmapFactory.Options();
options.inJustDecodeBounds=true;//不在內存中讀取圖片
options.inPreferredConfig = Bitmap.Config.RGB_565;//代表RGB位圖
options.inSampleSize=2;//縮放值:1不縮放 2爲縮放1/2
BitmapFactory.decodeFile(filepath, options);//壓縮前圖片
options.inJustDecodeBounds=false;//在內存中創建圖片
Bitmap bm = BitmapFactory.decodeFile(filepath, options);//壓縮後的圖片
try {
FileOutputStream fos = new FileOutputStream(filepath);
bm.compress(Bitmap.CompressFormat.JPEG, 15, fos);//壓縮圖片
fos.close();
}catch (IOException e){
// e.printStackTrace();
}
return bm;
}
}