ByteArrayOutputStream baos = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100 , baos); int options = 100 ; while ( baos.toByteArray().length / 1024 > 100 ) { baos.reset(); image.compress(Bitmap.CompressFormat.JPEG, options, baos); options -= 10 ; } ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray()); Bitmap bitmap = BitmapFactory.decodeStream(isBm, null , null );
首先该方法会先把图片100质量压进输出流里,然后判断输出流的长度,如果输出流的长度大于100kb的话,即图片在内存中的占的大小大于100KB,就会进行循环,以每次减少10质量的的方式进行压缩。但是当我使用了这个方法为图片进行压缩之后,程序报出了illegalArgument这个异常,进行跟踪发现错误出在循环内部的压缩代码里。于是我debug了下,发现了问题。图片第一次压缩,baos的长度大于100,然后进入循环进行压缩,压缩完了之后baos的长度依久不变,而options经过不断的循环值会达到负数从而程序异常。后来通过查询各种资料了解了问题:这种压缩方式称之为质量压缩,它是在改变图片的位深及透明度,在保证像素不变和图片质量的同时对图片进行压缩,压缩之后的图片文件大小会发生改变,但是图片占用内存的大小却不会发生改变。
ByteArrayOutputStream out = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 100, out); BitmapFactory.Options newOpts = new BitmapFactory.Options(); int be = 2; newOpts.inSampleSize = be; ByteArrayInputStream isBm = new ByteArrayInputStream(out.toByteArray()); Bitmap bitmap = BitmapFactory.decodeStream(isBm, null , <span style="line-height: 27.2px; font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif;">newOpts </span><span style="line-height: 27.2px; font-family: 'Helvetica Neue', Helvetica, Tahoma, Arial, STXihei, 'Microsoft YaHei', 微软雅黑, sans-serif;">);</span>
ByteArrayOutputStream out = new ByteArrayOutputStream(); image.compress(Bitmap.CompressFormat.JPEG, 85, out); float zoom = (float)Math.sqrt(size * 1024 / (float)out.toByteArray().length); Matrix matrix = new Matrix(); matrix.setScale(zoom, zoom); Bitmap result = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true); out.reset(); result.compress(Bitmap.CompressFormat.JPEG, 85, out); while(out.toByteArray().length > size * 1024){ System.out.println(out.toByteArray().length); matrix.setScale(0.9f, 0.9f); result = Bitmap.createBitmap(result, 0, 0, result.getWidth(), result.getHeight(), matrix, true); out.reset(); result.compress(Bitmap.CompressFormat.JPEG, 85, out); }这种压缩方式是通过缩放进行压缩。
/** * * 创建一个指定大小的缩略图 * @param source 源文件(Bitmap类型) * @param width 压缩成的宽度 * @param height 压缩成的高度 */ ThumbnailUtils.extractThumbnail(source, width, height);