Android BitmapFactory圖片壓縮處理(大位元影像二次採樣壓縮處理)

來源:互聯網
上載者:User

標籤:android   圖片 壓縮   

Android實際開發中,在載入大量圖片的時候,比如ViewPager、GridView、ListView中,載入了大量的比較大圖片就容易出現OOM(記憶體溢出)的異常,這是因為一個應用的最大記憶體使用量只有16M,超過了這個值,就會出現OOM。所以我們實際開發中,要想避免OOM出現就要對相應的圖片進行壓縮處理。

本文即使用了BitmapFactory和BitmapFactory.Option這兩個類,對圖片進行相應的尺寸壓縮處理。經測試,成功解決了未壓縮圖片之前出現的OOM異常。

實現:

本Demo使用的圖片大小為2M左右(壓縮以前)。

我壓縮圖片之前:

我這裡將壓縮的代碼注釋掉了:


運行結果:


進行壓縮處理後的圖片:

壓縮後圖片大小為:


大約為98KB


運行結果:


原始碼:


布局檔案:

activity_main:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".MainActivity" >    <ListView        android:id="@+id/listView"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true" >    </ListView></RelativeLayout>

list_item.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal" >    <ImageView        android:id="@+id/imageView"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"         android:layout_marginLeft="20dp"/></LinearLayout>


MainActivity:

package com.android_bitmapcompressdemo;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;public class MainActivity extends Activity {private ListView listView;private MyAdapter adapter;private int[] items = new int[] { R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc, R.drawable.pc, R.drawable.pc,R.drawable.pc, R.drawable.pc };@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView = (ListView) findViewById(R.id.listView);adapter = new MyAdapter(this, items);listView.setAdapter(adapter);adapter.notifyDataSetChanged();}}


ListView適配器:MyAdapter:

package com.android_bitmapcompressdemo;import android.content.Context;import android.graphics.Bitmap;import android.util.Log;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;public class MyAdapter extends BaseAdapter {private int[] items = new int[] {};private Context context;private String TAG = "zhongyao";private Bitmap bitmap = null;public MyAdapter(Context context, int[] items) {this.context = context;this.items = items;}@Overridepublic int getCount() {return items.length;}@Overridepublic Object getItem(int position) {return items[position];}@Overridepublic long getItemId(int position) {return position;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {ViewHolder holder;if (convertView == null) {convertView = LayoutInflater.from(context).inflate(R.layout.list_item, null);holder = new ViewHolder();holder.imageView = (ImageView) convertView.findViewById(R.id.imageView);holder.textView = (TextView) convertView.findViewById(R.id.textView);convertView.setTag(holder);}else {holder = (ViewHolder) convertView.getTag();}bitmap = BitmapCompressTools.decodeSampledBitmapFromResource(context.getResources(), R.drawable.pc, 100, 100);Log.d(TAG, "壓縮之後的圖片大小為:" + bitmap.getByteCount());holder.imageView.setImageBitmap(bitmap);holder.textView.setText("圖片"+position);return convertView;}class ViewHolder {ImageView imageView;TextView textView;}}

BitmapCompressTools(壓縮公用程式類):

package com.android_bitmapcompressdemo;import android.content.res.Resources;import android.graphics.Bitmap;import android.graphics.BitmapFactory;public class BitmapCompressTools {public static Bitmap decodeSampledBitmapFromResource(Resources res,int resId, int reqWidth, int reqHeight) {// 給定的BitmapFactory設定解碼的參數final BitmapFactory.Options options = new BitmapFactory.Options();// 從解碼器中擷取原始圖片的寬高,這樣避免了直接申請記憶體空間options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);// Calculate inSampleSizeoptions.inSampleSize = calculateInSampleSize(options, reqWidth,reqHeight);// 壓縮完後便可以將inJustDecodeBounds設定為false了。options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);}/** * 指定圖片的縮放比例 *  * @param options * @param reqWidth * @param reqHeight * @return */public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {// 原始圖片的寬、高final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;//if (height > reqHeight || width > reqWidth) {////這裡有兩種壓縮方式,可供選擇。///**// * 壓縮方式二// *///// final int halfHeight = height / 2;//// final int halfWidth = width / 2;//// while ((halfHeight / inSampleSize) > reqHeight//// && (halfWidth / inSampleSize) > reqWidth) {//// inSampleSize *= 2;//// }///** * 壓縮方式一 */// 計算壓縮的比例:分為寬高比例final int heightRatio = Math.round((float) height/ (float) reqHeight);final int widthRatio = Math.round((float) width / (float) reqWidth);inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;//}return inSampleSize;}}

達到了預期效果,但是寫到這裡滑動ListView的時候,還是會有些卡頓,有這方面解決經驗的可以給我留言討論。

原始碼已上傳到資源中,可到我的資源中下載。


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.