iis服务器助手广告广告
返回顶部
首页 > 资讯 > 移动开发 >Android Bitmap压缩方法的选择详解
  • 822
分享到

Android Bitmap压缩方法的选择详解

选择方法bitmapAndroid 2022-06-06 07:06:40 822人浏览 薄情痞子
摘要

刚刚修改Bug碰到了一个问题,先描述一下问题。 1.测试说分享文章到微信失败,QQ成功。 定位到微信分享接口。 2.分享其它文章到微信成功。 接口有问题!差点就找接口了,

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

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

定位到微信分享接口。

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

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

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

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

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

开始解决问题

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


{
  "title":"how to begain Android?",
  "content":"do it, do it, do it",
  "picture":"/file/imgs/upload/202206/06/nqdh1ylkvge.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 通过uri获取bitmap图片并压缩Android Bitmap压缩方式分析Android实现图片压缩(bitmap的六种压缩方式)android bitmap compress(图片压缩)代码详解Android Bitmap的常用压缩方式


--结束END--

本文标题: Android Bitmap压缩方法的选择详解

本文链接: https://www.lsjlt.com/news/23800.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作