android 中对图片尺度压缩和质量压缩


     在我们Android的实际开发中,显示很多图片,总会出现内存溢出的问题。为了避免出现OOM,我们总会使用到图片压缩,LruCache技术。今天,我这里说说图片的压缩技术,尺度压缩和质量压缩。

  首先我们了解基本的概念,尺度压缩是指:设置采样率,减少像素点,达到图片的压缩;

	/**
	 *    对图片进行尺度压缩
	 * */
	public static Bitmap zoomBitmap(String path){
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		// 开始读入图片,此时把options.inJustDecodeBounds 设回true了
		newOpts.inJustDecodeBounds = true;
		BitmapFactory.decodeFile(path, newOpts);
		int w = newOpts.outWidth;
		int h = newOpts.outHeight;
		float hh = 800f;// 这里设置高度为800f
		float ww = 480f;// 这里设置宽度为480f
		// 缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
		int be = 1;// be=1表示不缩放
		if (w > h && w > ww) {
			be = (int) (newOpts.outWidth / ww);
		} else if (w < h && h > hh) {
			be = (int) (newOpts.outHeight / hh);
		}
		if (be <= 0)
			be = 1;
		newOpts.inSampleSize = be;// 设置缩放比例
		// 重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
		newOpts.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, newOpts);
	}
           图片压缩关键点是:设置边界属性为true,然后设置采样比,最后设置边界属性,读取图片。边界数据设置为true,Google这样解释的:
   /**
         * If set to true, the decoder will return null (no bitmap), but
         * the out... fields will still be set, allowing the caller to query
         * the bitmap without having to allocate the memory for its pixels.
         */
        public boolean inJustDecodeBounds;

      就是不会图片分配内存,但是我们可以获取图片的属性,高和宽。采样比的计算:原图片的图片的高和宽和我们想要显示的图片高宽大小的比值最小。计算如下:

	public static int computeImageSampleSize(int srcWidth, int srcHeight, int targetWidth,
			int targetHeight) {
		int widthScale = (int) Math.ceil((float) srcWidth / targetWidth);
		int heightScale = (int) Math.ceil((float) srcHeight / targetHeight);
		return Math.min(widthScale, heightScale); 
	}

 质量压缩:减少图片的透明度,和饱和度,而Bitmap内存大小不会变,就是图片的高度和宽度不会变;

	/**
	 * 对bitmap进行质量压缩
	 * */
	private static Bitmap compressImage(Bitmap image) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		image.compress(Bitmap.CompressFormat.JPEG, 100, baos);// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
		int options = 100;
		while (baos.toByteArray().length / 1024 > 100) { // 循环判断如果压缩后图片是否大于100kb,大于继续压缩
			baos.reset();// 重置baos即清空baos
			image.compress(Bitmap.CompressFormat.JPEG, options, baos);// 这里压缩options%,把压缩后的数据存放到baos中
			options -= 10;// 每次都减少10
		}
		ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());// 把压缩后的数据baos存放到ByteArrayInputStream中
		Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);// 把ByteArrayInputStream数据生成图片
		return bitmap;
	}
质量压缩,只要设置压缩率:上面的代码是把图片质量压缩到100Kb以内,最后返回bitmap。


好了,今天就说到这了,希望对大家有所帮助。

你可能感兴趣的:(Android学习之路,Android,图片压缩,OOM)