• Android BitmapFactory图片压缩处理(大位图二次採样压缩处理)


    Android实际开发中。在载入大量图片的时候。比方ViewPager、GridView、ListView中,载入了大量的比較大图片就easy出现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 };
    	@Override
    	protected 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;
    	}
    
    	@Override
    	public int getCount() {
    		return items.length;
    	}
    
    	@Override
    	public Object getItem(int position) {
    		return items[position];
    	}
    
    	@Override
    	public long getItemId(int position) {
    		return position;
    	}
    
    	@Override
    	public 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 inSampleSize
    		options.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的时候,还是会有些卡顿,有这方面解决经验的能够给我留言讨论。

    源码已上传到资源中,可到我的资源中下载。


  • 相关阅读:
    自己上手写性能测试工具(一)
    你的领导真的很傻X吗?
    微软自动化测试工具palywright
    虫师『性能测试』文章大汇总
    虫师『软件测试』基础 与 测试杂谈
    「UI 测试自动化selenium」汇总
    web测试02
    web测试01
    测试20
    测试19
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/5307150.html
Copyright © 2020-2023  润新知