因为使用的图片大多是手机摄像头拍摄出来的图片,图片都比较大,所以在listview加载的时候,很容易出现OOM,这几天没事儿的时候就找了下压缩图片的方法,将图片复制到TuJi目录的时候,同时生成一张缩略图,用于在listview中显示,避免出现OOM,今天就总结一下所用到的压缩方法
BitmapFactory.Options
在选择图片的时候,会返回一个InputStream,这个时候,可以使用BitmapFactory.Options类,该方法提供了两个成员变量:
1. inJustDecodeBounds,当该变量为true的时候,在decodeStream的时候,不会将图片加载的内存中,但是我们可以读取图片的一些信息,譬如真实的宽、高等
2. inSampleSize,该变量用来设置缩放比例
当我们通过图片实际的大小获取到我们需要的缩放比例之后,将inJustDecodeBounds设置为false,这时候再decodeStream的时候,返回的bitmap就是按照我们设置的比例缩放过的bitmap。
bitmap.createScaleBitmap
createScaleBitmap方法可以按照你要求的比例将一个bitmap进行缩放并返回一个新的bitmap
Bitmap.createBitmap
Bitmap.createBitmap(source, x, y, width, height)该方法用来在一个bitmap中的某个位置开始截取一个固定宽高的图像,然后返回一个新的bitmap
参数:
source:要截取的bitmap
x:开始点的x轴坐标
y:开始点的y轴坐标
width:截取图片的宽
height:截取图片的高
AddPicActivity.java
package cn.lixyz.tuji; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Date; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Intent; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.ExifInterface; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import cn.lixyz.tuji.Util.GetDate; import cn.lixyz.tuji.sqlite.MySQLiteOpenHelper; /** * 添加图片类 选择图片之后,先判断用户是否安装SD卡,如果安装,则在SD卡中新建一个cn.lixyz.tuji目录,将选择的图片复制到目录中 * * @author LGB * */ public class AddPicActivity extends Activity implements View.OnClickListener { private ImageView iv_select_img; private EditText et_image_name, et_image_tag, et_image_remark; private Button bt_submit; private Bitmap bitmap; private File sdPath; private String fileName = "TUJIE" + new Date().getTime(); private FileOutputStream fos; private MySQLiteOpenHelper msoh; private SQLiteDatabase database; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_addpic); initView(); } private void initView() { iv_select_img = (ImageView) findViewById(R.id.iv_select_img); et_image_name = (EditText) findViewById(R.id.et_image_name); et_image_tag = (EditText) findViewById(R.id.et_image_tag); et_image_remark = (EditText) findViewById(R.id.et_image_remark); bt_submit = (Button) findViewById(R.id.bt_submit); iv_select_img.setOnClickListener(this); bt_submit.setOnClickListener(this); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK) { Uri uri = data.getData(); ContentResolver cr = this.getContentResolver(); try { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(cr.openInputStream(uri), null, options); int scale = options.outHeight / 150; options.inSampleSize = scale; options.inJustDecodeBounds = false; bitmap = BitmapFactory.decodeStream(cr.openInputStream(uri), null, options); Log.d("TTTT", bitmap.getWidth() + "--" + bitmap.getHeight()); iv_select_img.setImageBitmap(bitmap); // 将原始bitmap发送到handler,以便于复制到TuJi目录和压缩生成缩略图 Message msg = new Message(); msg.obj = BitmapFactory.decodeStream(cr.openInputStream(uri)); handler.sendMessage(msg); } catch (FileNotFoundException e) { Log.e("Exception", e.getMessage(), e); } catch (IOException e) { e.printStackTrace(); } } } // 创建一个Handler,用来异步复制图片到TuJi目录 Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); final Bitmap copyBitmap = (Bitmap) msg.obj; new Thread(new Runnable() { @Override public void run() { try { copyPicToSDCard(copyBitmap, true); Bitmap newBitmap = copyBitmap.createScaledBitmap(copyBitmap, 100, 100, true); copyPicToSDCard(newBitmap, false); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } }; @Override public void onClick(View v) { switch (v.getId()) { case R.id.iv_select_img: Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(intent, 1); break; case R.id.bt_submit: String picName = et_image_name.getText().toString().trim(); String picTag = et_image_tag.getText().toString().trim(); String picRemark = et_image_remark.getText().toString().trim(); msoh = new MySQLiteOpenHelper(AddPicActivity.this, "TujiData", null, 1); database = msoh.getWritableDatabase(); ContentValues cv = new ContentValues(); cv.put("picName", picName); cv.put("picTag", picTag); cv.put("picRemark", picRemark); cv.put("fileName", fileName); cv.put("date", new GetDate().getDate()); database.insert("pics", null, cv); database.close(); finish(); break; } } /** * * @param bm * bitmap * @param bigOrSmall * 原始图片or缩略图,true为原始图,false为缩略图 * @throws IOException */ private void copyPicToSDCard(Bitmap bm, boolean bigOrSmall) throws IOException { if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) { /* 得到SD卡得路径 */ sdPath = Environment.getExternalStorageDirectory(); try { File dir = new File(sdPath + "/cn.lixyz.TuJi"); if (bigOrSmall) { fos = new FileOutputStream(new File(dir + "/" + fileName + ".png")); } else { fos = new FileOutputStream(new File(dir + "/" + fileName + "_scale.png")); } if (!dir.exists()) { dir.mkdir(); bm.compress(Bitmap.CompressFormat.PNG, 100, fos); } else { bm.compress(Bitmap.CompressFormat.PNG, 100, fos); } } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { fos.flush(); fos.close(); } } } }
因为使用的图片大多是手机摄像头拍摄出来的图片,图片都比较大,所以在listview加载的时候,很容易出现OOM,这几天没事儿的时候就找了下压缩图片的方法,将图片复制到TuJi目录的时候,同时生成一张缩略图,用于在listview中显示,避免出现OOM,今天就总结一下所用到的压缩方法