聊聊Android中Bitmap缩放

最近在学IOS,发现IOS加载图片不像Android那样,动不动就OOM(Out of memory),下面看看一个比较通用的方法。。

先摆个阵

先上个布局文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<LinearLayout 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:orientation="vertical" >


<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="showThumbImage"
android:text="获取自适应图" />


<ImageView
android:id="@+id/imageView"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scaleType="matrix" />


</LinearLayout>

Activity代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class extends Activity {

private ImageView mImageView;


protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mImageView = (ImageView) findViewById(R.id.imageView);
}

public void showThumbImage(View v) {

}
}

我们使用的图片

是一张3500?×?2625的图片,我们现在就让它缩放后显示到512MB的Android模拟器上面

图片

好啦,上车吧

Options的inSampleSize

BitmapFactory.decodeXXX中我们都可以看到有一个Options的参数。我们可以设置这个参数,从而使图片按照预期加载。

属性说明

下面是Options的两个基本属性:

  • inJustDecodeBounds:是否只加载图片的轮廓
  • inSampleSize:加载图片时加载原来的1/inSampleSize

1、当inJustDecodeBounds为true的时候,Android系统并不会去加载图片的具体数据,只会提取图片的轮廓信息。在这里我们就可以防止加载大图片进来的时候把内存给挤爆。
2、上面获取了宽高有怎样????这样我们就可以根据比例去挑中inSampleSize的值,inSampleSize可以告诉系统加载Bitmap的时候按照怎样的比例去加载(按照1/inSampleSize去加载),这样在加载进来系统之前就已经处理好了,就不会挤爆内存了。

代码

1
2
3
public void showThumbImage(View v) {
mImageView.setImageBitmap(thumbImageWithInSampleSize(mImageView.getWidth(), mImageView.getHeight()));
}
1
2
3
4
5
6
7
8
9
10
大专栏  聊聊Android中Bitmap缩放11
12
13
14
public Bitmap thumbImageWithInSampleSize(float destWidth, float destHeight) {
Options opt = new Options();
opt.inJustDecodeBounds = true;

BitmapFactory.decodeResource(getResources(), R.drawable.img, opt);
double scaleW = Math.max(destWidth, opt.outWidth) / (Math.min(destWidth, opt.outWidth) * 1.0);
double scaleH = Math.max(destHeight, opt.outHeight) / (Math.min(destHeight, opt.outHeight) * 1.0);
opt.inSampleSize = (int) Math.max(scaleW, scaleH);

opt.inJustDecodeBounds = false;

bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.img, opt);
return bitmap;
}
  • 上面通过测试,图片可以正常显示出来。第一次设置inJustDecodeBounds = true是告诉Android系统不去加载Bitmap 的具体数据。计算完inSampleSize之后真正去加载的时候别忘了设置inJustDecodeBounds = false
  • 但是inSampleSize也有自身的缺点,就是只能缩放整数倍,所以很多时候可能不会自适应,这时候我们可以通过设置图片拉伸或者填充等方法达到预期效果。在强调不失真的情况下,也可以使用四舍五入的方法:
1
2
double scaleW = Math.max(destWidth, opt.outWidth) / (Math.min(destWidth, opt.outWidth) * 1.0) - 0.5;
double scaleH = Math.max(destHeight, opt.outHeight) / (Math.min(destHeight, opt.outHeight) * 1.0) - 0.5;

使用-0.5是因为最后缩放的是1/inSampleSize倍。

下面的方法慎用

因为图片始终会加载到内存中,所以如果是OOM的话就使用上面的方法。
下面的方法只是提供缩放图片的思路

使用矩阵变换

矩阵在图像领域中的应用非常广泛,只要给出对应的矩阵,就能实现缩放、平移等操作。但是在Android中我们并不需要自己构造矩阵,一切早已被封装好了。例如下面的matrix.postScale(scaleW,scaleH),直接得到特定缩放比例后的矩阵。

1
2
3
public void showThumbImage(View v) {
mImageView.setImageBitmap(thumbImageWithMatrix(mImageView.getWidth(), mImageView.getHeight()));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
public Bitmap thumbImageWithMatrix(float destWidth, float destHeight) {
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.img);
float bitmapOrgW = bitmapOrg.getWidth();
float bitmapOrgH = bitmapOrg.getHeight();

float bitmapNewW = (int) destWidth;
float bitmapNewH = (int) destHeight;

Matrix matrix = new Matrix();
matrix.postScale(bitmapNewW / bitmapOrgW, bitmapNewH / bitmapOrgH);
bitmapOrg.recycle();
return Bitmap.createBitmap(bitmapOrg, 0, 0, (int) bitmapOrgW, (int) bitmapOrgH, matrix, true);
}

ThumbnailUtils

其实Android也给我们提供一个ThumbnailUtils工具类,直接就可以生成缩略图,不过跟上面一样,需要去先加载Bitmap,所以也不能解决OOM错误

1
2
3
public void showThumbImage(View v) {
mImageView.setImageBitmap(thumbImageWithThumbnailUtils(mImageView.getWidth(), mImageView.getHeight()));
}
1
2
3
4
5
6
public Bitmap thumbImageWithThumbnailUtils(float destWidth, float destHeight) {
Bitmap bitmapOrg = BitmapFactory.decodeResource(getResources(), R.drawable.img);
Bitmap bitmap = ThumbnailUtils.extractThumbnail(bitmapOrg, (int) destWidth, (int) destHeight);
bitmapOrg.recycle();
return bitmap;
}
相关文章
相关标签/搜索
蓝月亮料精选资料免费 开原市| 诏安县| 札达县| 扬中市| 通渭县| 聂荣县| 凤翔县| 永德县| 双辽市| 会宁县| 昌宁县| 含山县| 庄浪县| 建瓯市| 保靖县| 浦县| 遂平县| 崇阳县| 华蓥市| 石渠县| 西乡县| 勃利县| 中宁县| 神农架林区| 邵武市| 青铜峡市| 贡觉县| 博客| 陆丰市| 汝城县| 海宁市| 滦南县| 关岭| 靖江市| 改则县| 柳州市| 屯留县| 米林县| 青浦区| 丽江市| 区。| 鱼台县| 囊谦县| 环江| 鹤庆县| 长武县| 石阡县| 苍溪县| 鄄城县| 景东| 绥德县| 无锡市| 巨野县| 永善县| 吴桥县| 建始县| 井研县| 广南县| 噶尔县| 乐山市| 什邡市| 泰宁县| 海伦市| 财经| 百色市| 资溪县| 高阳县| 宾川县| 稷山县| 张家界市| 内乡县| 崇义县| 富川| 长葛市| 长宁区| 乌拉特前旗| 临江市| 芷江| 梅河口市| 崇州市| 阿尔山市| 漳平市| 资源县| 齐河县| 邓州市| 东阿县| 淮阳县| 濉溪县| 桐庐县| 河间市| 张家川| 博罗县| 井研县| 鹰潭市| 浮山县| 陆川县| 汽车| 平安县| 平乡县| 柘荣县| 佛冈县| 衡阳市| 炎陵县| 安多县| 册亨县| 邵东县| 山阴县| 资兴市| 洛阳市| 霍州市| 来凤县| 徐汇区| 平邑县| 鲁甸县| 越西县| 通海县| 扶沟县| 庐江县| 雷州市| 六枝特区| 凤城市| 加查县| 朝阳县| 津市市| 雅江县| 渭南市| 朝阳区| 塔河县| 泗洪县| 涟水县| 全南县| 龙游县| 和林格尔县| 宿州市| 延庆县| 鹰潭市| 丰镇市| 仁怀市| 松江区| 格尔木市| 崇信县| 合水县| 麦盖提县| 扎鲁特旗| 林芝县| 贡觉县| 黄冈市| 昌图县| 伽师县| 兴化市| 安康市| 米易县| 额尔古纳市| 吉隆县| 温泉县| 宁海县| 阳信县| 英山县| 英山县| 汉寿县| 佳木斯市| 高邑县| 安宁市| 安福县| 阳城县| 玉门市| 梅河口市| 兰考县| 双柏县| 富锦市| 奉化市| 璧山县| 九龙坡区| 河源市| 鹤壁市| 罗山县| 新沂市| 兴海县| 新化县| 鸡泽县| 甘洛县| 永济市| 郎溪县| 得荣县| 仲巴县| 略阳县| 通道| 涡阳县| 弋阳县| 吉安县| 垦利县| 安福县| 安阳县| 石首市| 沁水县| 泸水县| 龙门县| 太仆寺旗| 株洲县| 永靖县| 长垣县| 沙坪坝区| 清新县| 宜州市| 马尔康县| 禹城市| 深州市| 盐池县| 神农架林区| 浦北县| 大名县| 鹰潭市| 宁蒗| 鲁甸县| 新和县| 汾西县| 法库县| 德昌县| 兴义市| 上蔡县| 介休市| 沈阳市| 裕民县| 铜梁县| 桃园县| 高州市| 沙河市| 修文县| 清水河县| 麻城市| 西畴县| 大城县| 兴国县| 遂昌县| 武义县| 资兴市| 新津县| 平顶山市| 汤原县| 秦安县| 水富县| 锡林郭勒盟| 临潭县| 汉寿县| 文水县| 邹平县| 荃湾区| 大连市| 牙克石市| 二手房| 右玉县| 佛坪县| 图木舒克市| 襄垣县| 石泉县| 贵阳市| 宝应县| 斗六市| 屏山县| 洛浦县| 隆回县| 德昌县| 六盘水市| 乌兰县| 镇巴县| 疏勒县| 汝南县| 廉江市| 新昌县| 那曲县| 永定县| 固原市| 石狮市| 芦山县| 抚顺县| 洪江市| 治多县| 改则县| 台南县| 天祝| 怀集县| 泸州市| 盖州市| 泾源县| 双流县| 铁力市| 绵竹市| 黄大仙区| 鲁山县| 社会| 中阳县| 南平市| 商水县| 株洲县| 莱州市| 乐业县| 南华县| 铜梁县| 福建省| 乌苏市| 民县| 寻甸| 嵊泗县| 泸西县| 二连浩特市| 普格县| 临清市| 台山市| 那曲县| 聂拉木县| 罗平县| 广水市| 奉化市| 武强县| 改则县| 长寿区| 西峡县| 成安县| 如东县| 龙里县| 都安| 东乌珠穆沁旗| 西和县| 扎鲁特旗| 宣城市| 桐乡市| 竹山县| 阳江市| 都江堰市| 津市市| 朔州市| 罗甸县| 凤阳县| 澜沧| 舟山市| 舟曲县| 庐江县| 汤阴县| 远安县| 德江县| 仲巴县| 年辖:市辖区| 务川| 汉源县| 宁津县| 奎屯市| 福清市| 赫章县| 宁晋县| 诸城市| 西宁市| 新沂市| 屏边| 新闻| 亚东县| 迁安市| 高陵县| 曲松县| 通江县| 小金县| 西充县| 南靖县| 喀喇沁旗| 天津市| 瑞安市| 江津市| 聂拉木县| 城市| 镇沅| 鹤庆县| 辰溪县| 景德镇市| 平和县| 睢宁县| 大足县| 久治县| 兴业县| 闽侯县| 瓮安县| 许昌市| 霍城县| 沂水县| 汽车| 浙江省| 新昌县| 太仓市| 普陀区| 四平市| 怀安县| 贞丰县| 犍为县| 克什克腾旗| 宿州市| 高台县| 汶上县| 密山市| 商河县| 囊谦县| 棋牌| 呼图壁县| 井冈山市| 会泽县| 泽库县| 肥乡县| 呼图壁县| 库车县| 安岳县| 内乡县| 长春市| 潞城市| 三台县| 临猗县| 宜良县| 石景山区| 淮南市| 津市市| 南溪县| 汉阴县| 清苑县| 建昌县| 大连市| 宁河县| 神木县| 嘉黎县| 湛江市| 烟台市| 永宁县| 丽水市| 鄯善县| 四子王旗| 宝丰县| 开封县| 桂林市| 宁陕县| 屏边| 名山县| 荥经县| 河源市| 都江堰市| 南澳县| 合肥市| 广平县| 石屏县| 仙游县| 施秉县| 桐乡市| 盐津县| 陵川县| 黑龙江省| 西藏| 乌鲁木齐市| 逊克县| 台州市| 舞阳县| 凤凰县| 济宁市| 福建省| 抚宁县| 桑日县| 栖霞市| 沧州市| 广水市| 墨江| 梅河口市| 淳安县| 双牌县| 申扎县| 外汇| 乌鲁木齐县| 沂水县| 临邑县| 如东县| 洛浦县| 珠海市| 三江| 广德县| 嘉黎县| 武城县| 潞西市| 囊谦县| 海林市| 苍南县| 英德市| 望城县| 商水县| 仙游县| 丹江口市| 桓台县| 肥乡县| 祥云县| 江都市| 宣武区| 班玛县| 武川县| 湘阴县| 拉孜县| 静海县| 江阴市| 永嘉县| 依安县| 海伦市| 连江县| 峡江县| 丽水市| 买车| 扶沟县| 高淳县| 昭苏县| 洞口县| 晋州市| http://www.yqo9j9rl7v.fun http://wap.gz1980editc.fun http://www.yqo2j5rl5v.fun http://www.gz1980ezailc.fun http://www.bo2020bodys.fun http://www.yqo4j5rl9v.fun http://www.jvz0j6r5o.fun http://wap.gz1980articlec.fun http://wap.bo2020fantasys.fun http://wap.yqo0j5rl0v.fun http://www.gz1980inkc.fun http://wap.gz1980pickc.fun http://m.bo2020keeps.fun http://www.yqo4j1rl3v.fun http://wap.yqo8j0rl2v.fun