二次采样
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView imageView = (ImageView) findViewById(R.id.iv);
String filePath = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath() + File.separator + "map.bmp";
Bitmap bitmap = BitmapUtils.getBitmap(filePath, 400, 400);
// Bitmap bitmap = BitmapFactory.decodeFile(filePath);
imageView.setImageBitmap(bitmap);
}
}
public class BitmapUtils {
/**
* @param filePath 文件的绝对路径
* @param destWidth 控件的宽
* @param destHeight 控件的高
* @return
*/
public static Bitmap getBitmap(String filePath, int destWidth, int destHeight) {
/**********************************第一次采样**************************************/
//加载图片时的选项
BitmapFactory.Options options = new BitmapFactory.Options();
//是否只加载图片的边框
options.inJustDecodeBounds = true;
//加载图片,此时的加载只能够获取到图片的边框
BitmapFactory.decodeFile(filePath, options);
//获取原图的宽度
int outWidth = options.outWidth;
//获取原图的高度
int outHeight = options.outHeight;
Log.d("lenve", "getBitmap: outWidth:" + outWidth + ";outHeight:" + outHeight);
//缩放比例
int sampleSize = 1;
//计算缩放比例,sampleSize必须是2的n次幂
while (outWidth / sampleSize > destWidth || outHeight / sampleSize > destHeight) {
sampleSize *= 2;
}
Log.d("lenve", "getBitmap: sampleSize:" + sampleSize);
/*********************************第一次采样结束,第二次采样开始*****************************************/
//不仅仅只加载图像的边框,也加载图像中的像素点
options.inJustDecodeBounds = false;
//设置缩放比例
options.inSampleSize = sampleSize;
//ARGB_8888,表示一个像素点的透明度以及三原色各占8位,共计32位,即4个字节
//ALPHA_8,表示一个像素点只有透明度,没有三原色,此时,一个像素点占8位,即1个字节
//ARGB_4444,表示一个像素点的透明度以及三原色各占4位,共计16位,即2个字节
//RGB_565,这种色彩模式不能表示透明度,红绿蓝三色各占5、6、6位,共计16位,即2个字节
//设置图像的色彩模式,共有4种取值
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
//加载bitmap并返回
return BitmapFactory.decodeFile(filePath, options);
}
}
BitmapFactory在解码图片时,可以带一个Options,有一些比较有用的功能,比如:
* inTargetDensity表示要被画出来时的目标像素密度
* inSampleSize这个值是一个int,当它小于1的时候,将会被当做1处理,如果大于1,那么就会按照比例(1/inSampleSize)缩小bitmap的宽和高、降低分辨率,大于1时这个值将会被处置为2的倍数。例如,width=100,height=100,inSampleSize=2,那么就会将bitmap处理为width=50,height=50,宽高降为1/2,像素数降为1/4。
* inJustDecodeBounds字面意思就可以理解就是只解析图片的边界,有时如果只是为了获取图片的大小就可以用这个,而不必直接加载整张图片
* inPreferredConfig默认会使用ARGB_8888,在这个模式下一个像素点将会占用4个byte,而堆一些没有透明度要求或者图片质量要求不高的图片,可以使用RGB_565,一个像素只会占用2个byte,一下可以省下50%内存
* inPurgeable和inInputShareable这两个需要一起使用,BitmapFactory.java的源码里面有注释,大致意思是表示在系统内存不足时是否可以回收这个bitmap,有点类似软引用,但是实际在5.0以后这两个属性已经被忽略,因为系统认为回收后再解码实际会反而可能导致性能问题
* inBitmap官方推荐使用的参数,表示重复利用图片内存,减少内存分配,在4.4以前只有相同大小的图片内存区域可以复用,4.4以后只要原有的图片比将要解码的图片大即可以复用了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现