热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

AndroidBitmap压缩方法的选择详解

这篇文章主要介绍了AndroidBitmap压缩方法的选择的相关资料,需要的朋友可以参考下

刚刚修改Bug碰到了一个问题,先描述一下问题。

1.测试说分享文章到微信失败,QQ成功。

定位到微信分享接口。

2.分享其它文章到微信成功。

接口有问题!差点就找接口了,还好没

3.断点微信分享,发现突然压缩失败。

代码写法问题,下面会分解

4.找到原因,微信对分享缩略图大小有32k的限制,代码是对文章的第一张图片进行压缩,图片太大,压缩代码也有问题。

开始解决问题

这里有两种解决方法:
1.接口提供文章对应的分享内容,在编辑人员编辑文章的时候就对这些数据进行了限制。

{
  "title":"how to begain Android?",
  "content":"do it, do it, do it",
  "picture":"http://192.168.0.1/pic/2015/09/02/share_thumb.jpg"
  ...
  ...
}

picture字段是<32K的缩略图。

ps:就我现在的水平来说,个人觉得这种是最好的,不是说Android省事,而是对于今后的扩展和整体项目的扩展规划来说都是比较好的,当然,水平有限,也许我看得还不够远,希望指教。

2.对获取的文章图片进行压缩。

当前项目无法对接口进行修改(骆驼太大了),所以只能对图片进行压缩了,这就谈到上面的坑了。先看原来写的压缩代码:

----可能出错的代码----

int optiOns= 100; 

ByteArrayOutputStream outputs = new ByteArrayOutputStream(); 
oBitmap.compress(Bitmap.CompressFormat.JPEG, options, outputs); //

while ( outputs.toByteArray().length / 1024 > 32 ) { 
  outputs.reset();
  oBitmap.compress(Bitmap.CompressFormat.JPEG, options, outputs);
  options -= 10 ;
}

ByteArrayInputStream inputs = new ByteArrayInputStream(outputs.toByteArray()); 
Bitmap bitmap = BitmapFactory.decodeStream(inputs, null , null );

这里用了bitmap的compress()方法进行了所谓的'质量压缩',控制参数就是options的值,但是出问题的地方也就是这个options的值,当图片非常大的时候,即使options为0的时候,图片还是大于32K,这个时候在while中option就为负数了,再进行compress()操作就会抛出throw new IllegalArgumentException("quality must be 0..100");的错误。

原因:

使用compress()方法的options值进行压缩的方法是不会丢失像素的,只是通过修改图片的其它比如透明度等属性,使得图片大小变化而已,所以它就无法无限压缩,到达一个值之后就不会继续变小了。

解决:

第一时间想到的是进行质量压缩后,当options为0的时候,还是大于32K的话,就进行采样率压缩。

BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inSampleSize = 2;
bitmap = BitmapFactory.decodeFile(picturePath, newOpts);

每次判断bitmap的大小,对BitmapFactory.Options的inSampleSize进行+1或者-1(不能小于1)操作就好。但是inSampleSize的值为int类型,当图片很大的时候,1/2, 1/3, 1/4的差距还是有些大。所以只能放弃,最后采用了缩放的方法,先上代码:

public static byte[] WeChatBitmapToByteArray(Bitmap bmp, boolean needRecycle) {

  // 首先进行一次大范围的压缩

  ByteArrayOutputStream output = new ByteArrayOutputStream();
  bmp.compress(Bitmap.CompressFormat.JPEG, 100, output);
  float zoom = (float)Math.sqrt(32 * 1024 / (float)output.toByteArray().length); //获取缩放比例

  // 设置矩阵数据
  Matrix matrix = new Matrix();
  matrix.setScale(zoom, zoom); 

  // 根据矩阵数据进行新bitmap的创建
  Bitmap resultBitmap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);

  output.reset();

  resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);

  // 如果进行了上面的压缩后,依旧大于32K,就进行小范围的微调压缩
  while(output.toByteArray().length > 32 * 1024){
    matrix.setScale(0.9f, 0.9f);//每次缩小 1/10

    resultBitmap = Bitmap.createBitmap(
                  resultBitmap, 0, 0, 
                  resultBitmap.getWidth(), resultBitmap.getHeight(), matrix,true);

    output.reset();
    resultBitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
  }

  return result;
}

至此,暂时补上了这个一开始不规范导致的问题。当然,以上的解释都是从书本和我大互联网中获取的方法,我进行了一些整合,如果你也遇到的这个问题,也有幸这篇文章被你看到,能帮到一二,就是我的本意了。

通过此文希望能帮助到有需要的同学,谢谢大家对本站的支持!


推荐阅读
  • 说明: 虽然android可使用数据岛实现bean和view元素的绑定,不过对于一天到晚杀鸡拔毛的人来说,这种宰牛刀始终是用起来不够直观顺手 ... [详细]
  • 触发器是数据库中一种特殊类型的存储过程,其执行依赖于预定义的事件,而非直接调用。在数据库管理中,触发器主要用于实现数据完整性、自动化日志记录及复杂业务规则的执行。当对数据库中的表、视图等对象进行插入、更新或删除操作时,系统将自动激活相关的触发器,以确保数据的一致性和安全性。此外,通过合理设计和优化触发器,还可以显著提升数据库性能和响应速度。 ... [详细]
  • 超链接作为网页间的重要连接方式,不仅是信息流动的关键通道,还极大地提升了网络资源的可访问性和互联性。通过超链接,用户能够便捷地在不同网站和页面之间跳转,获取所需信息,促进了互联网内容的广泛传播与高效利用。 ... [详细]
  • 深入解析:开发笔记中的 this、call、bind 和 apply 方法详解
    深入解析:开发笔记中的 this、call、bind 和 apply 方法详解 ... [详细]
  • 第一次写这玩意,不知道什么时候能写完,今天项目比较近,期望年底能看完吧。先定个小目标20201228完成第1章Spring介绍第2章入门第3章在Spring中引入IoC和DI第4章 ... [详细]
  • classpath和classpath*区别:classpath:只会到你的class路径中查找找文件。classpath*:不仅包含class路径,还包括jar文件中(class ... [详细]
  • 一张思维导图带你梳理HashMap相关知识
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • P31 系统全面升级与PUT功能增强
    在P31系统的全面升级中,PUT功能得到了显著增强。具体而言,系统现在支持通过传递一组ID来批量更新或替换公司信息,但这种操作的实际应用场景较为有限,因为其影响范围较大。为了确保数据的安全性和准确性,建议仅在必要时使用此功能,并严格控制更新或新增URI对应资源的权限。 ... [详细]
  • Tornado硬件管理平台中的设备信息采集技术深入解析(三)
    深入解析 Tornado 硬件管理平台中的设备信息采集技术,本文聚焦于 `monitor.py` 脚本的关键字段分析。该脚本通过导入 `psutil`、`time` 和 `datetime` 模块,以及使用 `pprint` 进行数据格式化输出,实现对系统资源和设备状态的高效监控与数据采集。 ... [详细]
  • 敏捷开发对于众多经历过复杂编程项目的开发者而言,无疑是一项宝贵的实践。尽管敏捷方法能够加速项目交付,但快速迭代也可能导致较高的Bug率。然而,通过在后期进行严格的测试和持续改进,这些问题可以得到有效解决。此外,敏捷开发还强调团队协作、客户反馈和适应变化,这些因素共同促进了项目的成功。 ... [详细]
  • 如何在SharePoint 2013中使用不同用户身份进行登录操作
    在创建了SharePoint 2013网站后,我注意到其界面与2010版本有所不同,特别是缺少了“以其他用户身份登录”的功能,这对测试工作造成了不便。通过查阅一些国外的技术资源,最终找到了有效的解决方案。这一方法不仅解决了登录问题,还提升了多用户环境下的测试效率和安全性。 ... [详细]
  • 利用IDEA高效构建Maven Spring MVC项目环境
    本文详细介绍了如何使用IntelliJ IDEA高效搭建Maven Spring MVC项目环境。首先,通过创建一个新的Maven项目,设置好GroupId、ArtifactId和Version等基本信息。接着,配置项目的依赖和插件,确保Spring MVC框架能够顺利集成。最后,通过IDEA的内置工具完成项目的初始化和测试,为后续开发打下坚实基础。 ... [详细]
  • 点击上方蓝色“程序猿DD”,选择“设为星标”回复“资源”获取独家整理的学习资料!来源|https:github.comwizardbyronprinci ... [详细]
  • 深入解析Android中图像资源的内存占用问题及其优化策略
    在Android开发过程中,图像资源的内存占用是一个值得关注的问题。本文将探讨图像内存占用与哪些因素相关,包括设备性能的影响,并提供一系列优化策略,帮助开发者有效管理图像资源,提升应用性能。 ... [详细]
  • 本文详细解析了如何利用Appium与Python在真实设备上执行测试示例的方法。首先,需要开启手机的USB调试功能;其次,通过数据线将手机连接至计算机并授权USB调试权限。最后,在命令行工具中验证设备连接状态,确保一切准备就绪,以便顺利进行测试。 ... [详细]
author-avatar
泡泡
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有