Android图片压缩的实例详解

Android图片压缩的实例详解

在做微信分享的时候,由于分享的缩略图要求不得大于32K,否则不能调起微信,所以总结了一下Android图片的压缩问题,大部分资料都是来自网上各位的分享,自己只是完善或修改了一下,本着继续分享的精神,也方便自己记忆,于是总结如下。

android图片压缩主要有两种方式:1.压缩图片分辨率 2.压缩图片质量

一、先看压缩图片分辨率,很好理解,如本来1280*768的图片压缩为640*384大小。废话不说,直接上代码:


/**
   * 按比例压缩图片分辨率
   * @param inBitmap
   * @param outHeight 输出图片高度,可据此保持比例计算输出宽度
   * @param needRecycled 是否回收inBitmap
   * @return
   */
  public static Bitmap createScaledBitmapByOutHeight(Bitmap inBitmap, int outHeight, boolean needRecycled) {
    int bitmapHeight = inBitmap.getHeight();
    int bitmapWidth = inBitmap.getWidth();
    int outWidth = bitmapWidth * outHeight / bitmapHeight; 

    return createScaledBitmap(inBitmap, outWidth, outHeight, needRecycled);
  }  

  /**
   * 按比例压缩图片分辨率
   * @param inBitmap
   * @param outHeight 输出图片宽度,可据此保持比例计算输出高度
   * @param needRecycled 是否回收inBitmap
   * @return
   */
  public static Bitmap createScaledBitmapByOutWidth(Bitmap inBitmap, int outWidth, boolean needRecycled) {
    int bitmapHeight = inBitmap.getHeight();
    int bitmapWidth = inBitmap.getWidth();
    int outHeight = bitmapHeight * outWidth / bitmapWidth; 

    return createScaledBitmap(inBitmap, outWidth, outHeight, needRecycled);
  } 

  /**
   * 指定输出的宽高缩放图片
   * @param inBitmap
   * @param outWidth
   * @param outHeight
   * @param needRecycled
   * @return
   */
  public static Bitmap createScaledBitmap(Bitmap inBitmap, int outWidth, int outHeight, boolean needRecycled) {         

    Bitmap thumbBmp = Bitmap.createScaledBitmap(inBitmap, outWidth, outHeight, true);
    if (needRecycled) {
      inBitmap.recycle();
    } 

    return thumbBmp;
  }

前两个方法可以指定期望的宽度或高度,并按比例缩放图片的分辨率,第3个方法可以随意指定期望的宽高,缩放图片。

上面代码是对输入的bitmap进行缩放,还可以从资源或文件中加载图片并缩放,具体如下:

/**
   * 从资源加载并压缩图片
   * @param res
   * @param resId
   * @param outWidth 目标宽度
   * @param outHeight 目标高度
   * @return
   */
  public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
      int outWidth, int outHeight) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true; // 假解,来获取图片大小
    BitmapFactory.decodeResource(res, resId, options);
    options.inSampleSize = calculateInSampleSize(options, outWidth, outHeight);
    // 使用获取到的inSampleSize值再次解析图片
    options.inJustDecodeBounds = false;
    //options.inPreferredConfig = Config.RGB_565;
    return BitmapFactory.decodeResource(res, resId, options);
  }  

  /**
   * 从文件中加载并压缩图片
   * @param res
   * @param resId
   * @param outWidth 目标宽度
   * @param outHeight 目标高度
   * @return
   */
  public static Bitmap decodeSampledBitmapFromFile(String pathName, int outWidth, int outHeight) {
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true; // 假解,来获取图片大小
    BitmapFactory.decodeFile(pathName, options);
    options.inSampleSize = calculateInSampleSize(options, outWidth, outHeight);
    // 使用获取到的inSampleSize值再次解析图片
    options.inJustDecodeBounds = false;
    //options.inPreferredConfig = Config.RGB_565;
    return BitmapFactory.decodeFile(pathName, options);
  }  

  /**
   * 计算options.inSampleSize
   * @param options
   * @param reqWidth
   * @param reqHeight
   * @return
   */
  public static int calculateInSampleSize(BitmapFactory.Options options,
      int reqWidth, int reqHeight) {
    // 源图片的高度和宽度
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
    if (height > reqHeight || width > reqWidth) {
      // 计算出实际宽高和目标宽高的比率
      final int heightRatio = Math.round((float) height / (float) reqHeight);
      final int widthRatio = Math.round((float) width / (float) reqWidth);
      // 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高
      // 一定都会大于等于目标的宽和高。
      inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
    }
    return inSampleSize;
  }

二、压缩图片的质量

/**
   * 压缩图片质量,把图片压缩到outSize以内
   * @param inBitmap 原始bitmap
   * @param outSize 压缩到的大小
   * @param needRecycled 是否回收bitmap
   * @return
   */
  public static Bitmap compressImage(Bitmap inBitmap, int outSize, boolean needRecycled) {  

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    inBitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    int quality = 100;
    while (baos.toByteArray().length / 1024 > outSize) {
      if (quality <= 0) {
        ByteArrayInputStream outBais = new ByteArrayInputStream(baos.toByteArray());
        return BitmapFactory.decodeStream(outBais, null, null);// 如果quaLity为0时还未达到32k以内,返回得到的最小值;如需要可结合分辨率压缩
      }
      baos.reset();
      //PNG格式下,这种压缩不起作用(quality:0-100,如果目标大小太小,有时候质量压缩不一定能达到效果,需结合分辨率压缩)
      inBitmap.compress(Bitmap.CompressFormat.JPEG, quality, baos);
      Log.e("AN", "bitmap size:"+ baos.toByteArray().length / 1024 + "k");
      quality -= 10;
    }
    if (needRecycled) {
      inBitmap.recycle();
    } 

    ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
    Bitmap outBitmap= BitmapFactory.decodeStream(bais, null, null);//ByteArrayInputStream转成bitmap 

    return outBitmap;
  }

需要注意的是compress方法,该压缩方法只对JPEG格式有效,对于PNG格式,则会忽略第二个参数quality,即压缩不起作用。这种压缩只是对图片质量有影响,并不会改变图片大小。

当然,如有需要,以上两种压缩方法可以结合使用。

以上就是Android 图片压缩的实现方法的详解,如有疑问请留言或者到本站社区交流讨论,感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • Android图片压缩上传之基础篇

    在android程序开发中我们经常见到需要上传图片的场景,在这里有个技术点,需要把图片压缩处理,然后再进行上传.这样可以减少流量的消耗,提高图片的上传速度等问题. 关于android如何压缩,网上的资料也是很多,但大多数都是代码片段,讲解压缩步骤,而没有一个实用的工具类库.那么如何将压缩算法封装成一个实用工具库呢?其中会遇到些什么问题,比如: 1.需要压缩的图片有多少 2.压缩后的图片是覆盖还是保存到另外的目录 3.如果是另存目录需要将原始图片删除吗 4.如果改变压缩后的图片的尺寸大小是按照原图

  • Android WebP 图片压缩与传输

    1. 简介 直到4g时代,流量依然是宝贵的东西.而移动网络传输中,最占流量的一种载体:图片,成为了我们移动开发者不得不关注的一个问题. 我们关注的问题,无非是图片体积和质量如何达到一个比较和谐的平衡,希望得到质量不错的图片同时体积还不能太大. 走在时代前列的谷歌给出了一个不错的答案--WebP. WebP是一种图片文件格式,在相同的压缩指标下,webp的有损压缩能比jpg小 25-34%.而在我自己的测试里,有时候能小50%. 2. 大企业背书 WebP在2010年发布第一个版本,到现在已经6年

  • android bitmap compress(图片压缩)代码

    android的照相功能随着手机硬件的发展,变得越来越强大,能够找出很高分辨率的图片.有些场景中,需要照相并且上传到服务,但是由于图片的大小太大,那么就上传就会很慢(在有些网络情况下),而且很耗流量,要想速度快,那么就需要减小图片的大小.减少图片的大小有两种方法,1. 照小图片: 2. 压缩大图片. 照相时获取小图片一般不太符合要求,因为,图片的清晰度会很差,但是这种情况有个好处就是应用速度会快些: 压缩图片,就是把大图片压缩小,降低图片的质量,在一定范围内,降低图片的大小,并且满足需求(图片仍

  • 详解Android 图片的三级缓存及图片压缩

    为什么需要图片缓存 Android默认给每个应用只分配16M的内存,所以如果加载过多的图片,为了防止内存溢出,应该将图片缓存起来.图片的三级缓存分别是: 内存缓存 本地缓存 网络缓存 其中,内存缓存应优先加载,它速度最快:本地缓存次优先加载,它速度也快:网络缓存不应该优先加载,它走网络,速度慢且耗流量. 三级缓存的具体实现 网络缓存 根据图片的url去加载图片 在本地和内存中缓存 public class NetCacheUtils { private LocalCacheUtils mLoca

  • android图片压缩的3种方法实例

    android 图片压缩方法: 第一:质量压缩法: 复制代码 代码如下: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中        int op

  • android 将图片压缩到指定的大小的示例

    从网上收集后自己写的一个方法: 1.首先是一个根据分辨率压缩的类,首先对图片进行一次压缩 /** * 根据分辨率压缩图片比例 * * @param imgPath * @param w * @param h * @return */ private static Bitmap compressByResolution(String imgPath, int w, int h) { BitmapFactory.Options opts = new BitmapFactory.Options();

  • Android中3种图片压缩处理方法

    Android中图片的存在形式: 1:文件形式:二进制形式存在与硬盘中. 2:流的形式:二进制形式存在与内存中. 3:Bitmap的形式 三种形式的区别: 文件形式和流的形式:对图片体积大小并没有影响.也就是说,如果你手机SD卡上的图片通过流的形式读到内存中,在内存中的大小也是原图的大小. 注意:不是Bitmap的形式. Bitmap的形式:图片占用的内存会瞬间变大. 以下是代码的形式: /** * 图片压缩的方法总结 */ /* * 图片压缩的方法01:质量压缩方法 */ private Bi

  • Android图片压缩的实例详解

    Android图片压缩的实例详解 在做微信分享的时候,由于分享的缩略图要求不得大于32K,否则不能调起微信,所以总结了一下Android图片的压缩问题,大部分资料都是来自网上各位的分享,自己只是完善或修改了一下,本着继续分享的精神,也方便自己记忆,于是总结如下. android图片压缩主要有两种方式:1.压缩图片分辨率 2.压缩图片质量 一.先看压缩图片分辨率,很好理解,如本来1280*768的图片压缩为640*384大小.废话不说,直接上代码: /** * 按比例压缩图片分辨率 * @para

  • Android 帧动画的实例详解

    Android 帧动画的实例详解 对于 Android 帧动画 大体上可以理解成 一张张图片 按一定顺序切换, 这样当连续几张图是一组动画时,就可以连起来了看成是一个小电影,你懂得 好得,比就装到这里,下面开始进入正题,由于产品需求 需要做一个 声音喇叭动态切换的样式,我特么第一就想到是帧动画切换,然后就百度了一些资料,发现 真的, 现在这个网上太多的资料是 copy粘贴过来的, 一错全错,对于这种情况我只想说,made,一群垃圾, 所以今天我将带你们走进Android 正确帧动画地址. 第一步

  • Android 中ContentProvider的实例详解

    Android 中ContentProvider的实例详解 Content Provider 的简单介绍: * Android中的Content Provider 机制可支持在多个应用中存储和读取数据.这也是跨应用 共享数据的唯一方式.在Android系统中,没有一个公共的内存区域,供多个应用共享存储数据: * Android 提供了一些主要数据类型的ContentProvider ,比如:音频.视频.图片和私人通讯录等: 在android.provider 包下面找到一些android提供的C

  • Android PhotoView使用步骤实例详解

    Android PhotoView使用步骤实例详解 1.步骤一:在布局文件中的代码: <uk.co.senab.photoview.PhotoView android:id="@+id/img_showimgview" android:layout_width="match_parent" android:layout_height="match_parent" /> 2.步骤二:进行找到控件的id photoview = (Phot

  • Android之ImageSwitcher的实例详解

    Android之ImageSwitcher的实例详解 一. 简单示例 实例代码: public class AndroidUIActivity extends Activity { // 当前显示的图片索引 private int index; // 图片数组 private int[] images = { R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4, R.drawable.image5

  • Android Fragment的用法实例详解

    碎片,它的出现是为了更好展示UI的设计,让程序更加得到充分的展示.Fragment的出现,如微信的额主界面包含多个Fragment,使得微信功能更加简洁明了. Fragment组件 Fragment是Android 3.0的时候被引入的,主要目的是为了给大屏幕(如平板电脑)添加动态和灵活的UI支持.利用Fragment实现更好的用户体验. Fragment加载 1.静态加载:添加Fragment到Activity布局中,以xml的形式. 2.动态加载: <LinearLayout android

  • Android的搜索框架实例详解

    基础知识 Android的搜索框架将代您管理的搜索对话框,您不需要自己去开发一个搜索框,不需要担心要把搜索框放什么位置,也不需要担心搜索框影响您当前的界面.所有的这些工作都由SearchManager类来为您处理(以下简称"搜索管理器"),它管理的Android搜索对话框的整个生命周期,并执行您的应用程序将发送的搜索请求,返回相应的搜索关键字. 当用户执行一个搜索,搜索管理器将使用一个专门的Intent把搜索查询的关键字传给您在配置文件中配置的处理搜索结果的Activity.从本质上讲

  • Android Intent封装的实例详解

    Android Intent封装的实例详解 什么是Intent: Intent是协调应用间.组件之间的通讯和交互.通过Intent你可以启动Activity.Service.Broadcasts.更可以跨程序调用第三方组件.例如:启动拨打电话界面.音乐播放等. 组件     启动 Activity startActicity() Service startService(),bindService( ) Broadcasts sendBroadcast() 使用Intent: 栗子:在一个Act

  • Android 完全退出的实例详解

    Android 完全退出的实例详解 首先,在基类BaseActivity里,注册RxBus监听: public class BaseActivity extends AppCompatActivity { Subscription mSubscription; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Utils.intiSySBar(thi

  • Android 中 ActivityLifecycleCallbacks的实例详解

    Android 中 ActivityLifecycleCallbacks的实例详解           以上就是使用ActivityLifecycleCallbacks的实例,代码注释写的很清楚大家可以参考下, MyApplication如下: package com.cc; import java.util.LinkedList; import android.app.Activity; import android.app.Application; import android.os.Bun

随机推荐