默认情况下,bitmap每个像素点占用4个字节(ARGB_8888),比如一张3543×3503的图片差不多在内存中占用44M,安卓系统给每个应用分配的内存都是有限的,可以使用Runtime.getRuntime().maxMemory()来获取内存有限空间。默认情况下图片存储又需要大量的空间,于是就容易产生OOM(out of memory)。
本次需要显示的图片信息:宽高都为3500个像素,大小约为1.1M,通过imageView.setImageResource(R.drawable.bigpic);会产生out of memory,采用二次采样,就可以把图片显示出来。
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import com.example.dy.getpictrue.R;
@ContentView(R.layout.activity_main)
public class MainActivity extends AppCompatActivity {
@ViewInject(R.id.image)
private ImageView imageView;
final int MAX_WIDTH = 1000;//定义图片最大的宽
final int MAX_HEIGHT = 1000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ViewUtils.inject(this);
// imageView.setImageResource(R.drawable.bigpic);
Bitmap bitmap = compressImage();
imageView.setImageBitmap(bitmap);
}
/**
* 对图片进行二次采样,实际上就是对图片进行压缩
* 技术关键点就是不用将图片放到内存中,也能测量图片的宽高
*/
public Bitmap compressImage() {
//第一次采样
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;//只测量边框,而不把整张图片加载到内存
BitmapFactory.decodeResource(getResources(), R.drawable.bigpic, options);
int iWidth = options.outWidth;//测量出实际的宽
int iHeight = options.outHeight;//测量出实际的高
int iSimple = 1;//压缩比(采样率),2的倍数,simple等于4,表示压缩到原来的1/4.
while ((iWidth > MAX_WIDTH) || (iHeight > MAX_HEIGHT)) {
iSimple = iSimple * 2;
iWidth = iWidth / 2;
iHeight = iHeight / 2;
}
//第二次采样,根据压缩比压缩图片
options.inJustDecodeBounds = false;//解码整个压缩后的图片
options.inSampleSize = iSimple;//设置压缩比
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bigpic, options);
return bitmap;
}
}
效果如图: