图片压缩
2016-04-22 16:58
211 查看
最近在搞一个app 的上传图片评价功能,分别从相机相册中获取图片,然后要上传到服务器,但是如果上传的话那么图片就不能太大,不然太费流量了,所以要压缩下。
网上搜索了下压缩的方法,发现大部分的人都是用将文件转换为Bitmap压缩,然后再上传,我也试了试,发现如果用Bitmap 压缩的话压缩的太厉害图片的清晰度就不清晰了。
又捣鼓捣鼓,发现如果用btye 压缩的话就没这个问题,我用byte压缩把2M的图片压缩到小于50k竟然还是很清晰所以果断换byte的压缩方法。
方法如下:
首先通过相机和相册获取到uri ,这里就省略了,不多讲解了。
content 就是uri转换的byte,
ImageUtil.CompressBytes 是Byte压缩函数压缩后返回压缩后的byte。
saveMybyte(content) 函数是将压缩后的byte转换成新的文件。并返回新文件路径。
最后根据file_URL文件路径我们把这个临时的图片文件上传服务器,上传成功后可以调用ImageUtil.deleteTempFile(file_URL); 删除临时的压缩文件。以下是流程的大概代码:
上面的代码涉及到的函数如下:
ImageUtil.CompressBytes
saveMybyte
ImageUtil.byte2File
deleteTempFile
网上搜索了下压缩的方法,发现大部分的人都是用将文件转换为Bitmap压缩,然后再上传,我也试了试,发现如果用Bitmap 压缩的话压缩的太厉害图片的清晰度就不清晰了。
又捣鼓捣鼓,发现如果用btye 压缩的话就没这个问题,我用byte压缩把2M的图片压缩到小于50k竟然还是很清晰所以果断换byte的压缩方法。
方法如下:
首先通过相机和相册获取到uri ,这里就省略了,不多讲解了。
content 就是uri转换的byte,
ImageUtil.CompressBytes 是Byte压缩函数压缩后返回压缩后的byte。
saveMybyte(content) 函数是将压缩后的byte转换成新的文件。并返回新文件路径。
最后根据file_URL文件路径我们把这个临时的图片文件上传服务器,上传成功后可以调用ImageUtil.deleteTempFile(file_URL); 删除临时的压缩文件。以下是流程的大概代码:
byte[] content = null; uri = Uri.fromFile(picture); /picture图片文件 try { content = ImageUtil.readStream(getContentResolver().openInputStream( Uri.parse(uri.toString()))); Log.e("o2o", "压缩前文件大小 :" + content.length); content =ImageUtil.CompressBytes(content,50000); //小于50k Log.e("o2o", "压缩后文件大小 :" + content.length); file_URL=saveMybyte(content); //储存临时文件地址,上传成功后删除临时文件 } catch (Exception e) { e.printStackTrace(); }
上面的代码涉及到的函数如下:
ImageUtil.CompressBytes
public static byte[] CompressBytes(byte[] content, int max_size) { HashMap<String, Object> resultMap = new HashMap<String, Object>(); Bitmap bm; byte[] compressBytes = null; int rate = 100; int scale = (int) Math.floor(content.length / max_size); BitmapFactory.Options option = new BitmapFactory.Options(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); option.inJustDecodeBounds = false; option.inSampleSize = 1; if (scale < 2) { option.inSampleSize = 1; } else if (scale >= 2 && scale < 8) { option.inSampleSize = 2; } else if (scale >= 8 && scale < 32) { option.inSampleSize = 4; } else if (scale >= 32 && scale < 128) { option.inSampleSize = 8; } else { option.inSampleSize = 16; } try { bm = BitmapFactory.decodeByteArray(content, 0, content.length, option); } catch (OutOfMemoryError e) { option.inSampleSize *= 2; bm = BitmapFactory.decodeByteArray(content, 0, content.length, option); } do { if (compressBytes == null) { bm.compress(Bitmap.CompressFormat.JPEG, rate, baos); compressBytes = baos.toByteArray(); } else { rate = rate - 3; baos.reset(); compressBytes = null; System.gc(); bm.compress(Bitmap.CompressFormat.JPEG, rate, baos); compressBytes = baos.toByteArray(); } } while (compressBytes.length > max_size); bm = null; System.gc(); return compressBytes; }
saveMybyte
private String saveMybyte(byte[] content){ String absPath = null; //给文件取名字 以时间命名 防止重复 被覆盖 String picturename = DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg"; ImageUtil.byte2File(content,SessionManager.getInstance().getAppFileDirPath(),picturename); absPath = SessionManager.getInstance().getAppFileDirPath() + picturename; //存放在软件安装的地址 return absPath; }
ImageUtil.byte2File
/** * byte 转file * @param buf * @param filePath * @param fileName */ public static void byte2File(byte[] buf, String filePath, String fileName) { BufferedOutputStream bos = null; FileOutputStream fos = null; File file = null; try { File dir = new File(filePath); if (!dir.exists() && dir.isDirectory()) { dir.mkdirs(); } file = new File(filePath + File.separator + fileName); fos = new FileOutputStream(file); bos = new BufferedOutputStream(fos); bos.write(buf); } catch (Exception e) { e.printStackTrace(); } finally { if (bos != null) { try { bos.close(); } catch (IOException e) { e.printStackTrace(); } } if (fos != null) { try { fos.close(); } catch (IOException e) { e.printStackTrace(); } } } }
deleteTempFile
/** * 根据路径删除图片 * * @param path */ public static void deleteTempFile(String path) { File file = new File(path); if (file.exists()) { file.delete(); } }
相关文章推荐
- 从电子请柬切入,顺利融资3000万美金,“低频”的婚庆市场应该怎么做?
- cocos2d-C++ 学习UI控件(一)之 Button|CheckButton
- [Ruby] ruby创建类方法 ,以及class_eval 、instance_eval的使用
- Python IDLE reload(sys)后无法正常执行命令的原因
- jQuery学习(五)
- 阶段冲刺1
- TCP与UDP区别小结
- 路径
- java中main函数解析(转载)
- Docker 5分钟入门
- 《一个操作系统的实现》mount错误解决办法(mount 您必须指定文件系统的类型
- 自定义UIButton图片和文字的frame
- # sed 查找匹配行
- 连接打印机服务器
- more、which、find、chmod、tar、diff、grep、ps、netstat、uname
- 344. Reverse String
- Netty vs Mina
- UI Components for use with Angular2 and Bootstrap4
- SurfaceView与Timer实现动态绘图
- C++多重继承通过中间类继承重写不同基类中相同类型的虚函数