Android 图片压缩之多种压缩方式结合使用,阿里Android开发面试解答
canvas.drawBitmap(image, null, rect, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
result.compress(Bitmap.CompressFormat.JPEG, options, baos);
// 循环判断如果压缩后图片是否大于100kb,大于继续压缩
while (baos.toByteArray().length / 1024 > maxSize) {
// 重置baos即清空baos
baos.reset();
// 每次都减少10
options -= 10;
// 这里压缩options%,把压缩后的数据存放到baos中
result.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
// JNI调用保存图片到SD卡 这个关键
NativeUtil.saveBitmap(result, options, filePath, true);
// 释放Bitmap
if (result != null && !result.isRecycled()) {
result.recycle();
result = null;
}
}
五. NativeUtil类的源码
16.9.29更新
1、添加getBitmapFromFile()方法,解决OOM和图片旋转的问题
2、添加compressBitmap()方法,传递当前图片本地路径和解压后图片保存路径两个参数,即可,实现压缩
package net.bither.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.media.ExifInterface;
/**
JNI图片压缩工具类
@Description TODO
@Package net.bither.util
@Class NativeUtil
@Copyright: Copyright © 2015
@version V1.0.0
*/
public class NativeUtil {
private static int DEFAULT_QUALITY = 95;
/**
@Description: JNI基本压缩
@param bit
bitmap对象
@param fileName
指定保存目录名
@param optimize
是否采用哈弗曼表数据计算 品质相差5-10倍
@version V1.0.0
*/
public static void compressBitmap(Bitmap bit, String fileName, boolean optimize) {
saveBitmap(bit, DEFAULT_QUALITY, fileName, optimize);
}
/**
@Description: 通过JNI图片压缩把Bitmap保存到指定目录
@param image
bitmap对象
@param filePath
要保存的指定目录
@version V1.0.0
*/
public static void compressBitmap(Bitmap image, String filePath) {
// 最大图片大小 150KB
int maxSize = 150;
// 获取尺寸压缩倍数
int ratio = NativeUtil.getRatioSize(image.getWidth(),image.getHeight());
// 压缩Bitmap到对应尺寸
Bitmap result = Bitmap.createBitmap(image.getWidth() / ratio,image.getHeight() / ratio,Config.ARGB_8888);
Canvas canvas = new Canvas(result);
Rect rect = new Rect(0, 0, image.getWidth() / ratio, image.getHeight() / ratio);
canvas.drawBitmap(image,null,rect,null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int options = 100;
result.compress(Bitmap.CompressFormat.JPEG, options, baos);
// 循环判断如果压缩后图片是否大于100kb,大于继续压缩
while (baos.toByteArray().length / 1024 > maxSize) {
// 重置baos即清空baos
baos.reset();
// 每次都减少10
options -= 10;
// 这里压缩options%,把压缩后的数据存放到baos中
result.compress(Bitmap.CompressFormat.JPEG, options, baos);
}
// JNI保存图片到SD卡 这个关键
NativeUtil.saveBitmap(result, options, filePath, true);
// 释放Bitmap
if (!result.isRecycled()) {
result.recycle();
}
}
/**
@Description: 通过JNI图片压缩把Bitmap保存到指定目录
@param curFilePath
当前图片文件地址
@param targetFilePath
要保存的图片文件地址
@author XiaoSai
@date 2016年9月28日 下午17:43:15
@version V1.0.0
*/
public static void compressBitmap(String curFilePath, String targetFilePath) {
// 最大图片大小 150KB
int maxSize = 150;
//根据地址获取bitmap
Bitmap result = getBitmapFromFile(curFilePath);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
int quality = 100;
result.compress(Bitmap.CompressFormat.JPEG, quality, baos);
// 循环判断如果压缩后图片是否大于100kb,大于继续压缩
while (baos.toByteArray().length / 1024 > maxSize) {
// 重置baos即清空baos
baos.reset();
// 每次都减少10
quality -= 10;
// 这里压缩quality,把压缩后的数据存放到baos中
result.compress(Bitmap.CompressFormat.JPEG, quality, baos);
}
// JNI保存图片到SD卡 这个关键
NativeUtil.saveBitmap(result, quality, targetFilePath, true);
// 释放Bitmap
if (!result.isRecycled()) {
result.recycle();
}
}
/**
计算缩放比
@param bitWidth 当前图片宽度
@param bitHeight 当前图片高度
@return int 缩放比
@version V1.0.0
*/
public static int getRatioSize(int bitWidth, int bitHeight) {
// 图片最大分辨率
int imageHeight = 1280;
int imageWidth = 960;
// 缩放比
int ratio = 1;
// 缩放比,由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
if (bitWidth > bitHeight && bitWidth > imageWidth) {
// 如果图片宽度比高度大,以宽度为基准
ratio = bitWidth / imageWidth;
} else if (bitWidth < bitHeight && bitHeight > imageHeight) {
// 如果图片高度比宽度大,以高度为基准
ratio = bitHeight / imageHeight;
}
// 最小比率为1
if (ratio <= 0)
ratio = 1;
return ratio;
}
/**
通过文件路径读获取Bitmap防止OOM以及解决图片旋转问题
@param filePath
@return
*/
public static Bitmap getBitmapFromFile(String filePath){
BitmapFactory.Options newOpts = new BitmapFactory.Options();
newOpts.inJustDecodeBounds = true;//只读边,不读内容
BitmapFactory.decodeFile(filePath, newOpts);
int w = newOpts.outWidth;
int h = newOpts.outHeight;
// 获取尺寸压缩倍数
newOpts.inSampleSize = NativeUtil.getRatioSize(w,h);
newOpts.inJustDecodeBounds = false;//读取所有内容
newOpts.inDither = false;
newOpts.inPurgeable=true;
newOpts.inInputShareable=true;
newOpts.inTempStorage = new byte[32 * 1024];
Bitmap bitmap = null;
File file = new File(filePath);
FileInputStream fs = null;
try {
fs = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if(fs!=null){
bitmap = BitmapFactory.decodeFileDescriptor(fs.getFD(),null,newOpts);
//旋转图片
int photoDegree = readPictureDegree(filePath);
if(photoDegree != 0){
Matrix matrix = new Matrix();
matrix.postRotate(photoDegree);
// 创建新的图片
bitmap = Bitmap.createBitmap(bitmap, 0, 0,
bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if(fs!=null) {
try {
fs.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
/**
读取图片属性:旋转的角度
@param path 图片绝对路径
@return degree旋转的角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(
ExifInterface.TAG_ORIENTATION,
ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
调用native方法
@Description:函数描述
@param bit
@param quality
@param fileName
最后
其实Android开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的百度、腾讯、网易、字节跳动、阿里等公司2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
Android学习PDF+学习视频+面试文档+知识点笔记
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
【Android高级架构视频学习资源】
以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
上面分享的百度、腾讯、网易、字节跳动、阿里等公司2021年的高频面试题,博主还把这些技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,上面只是以图片的形式给大家展示一部分。
Android学习PDF+学习视频+面试文档+知识点笔记
【Android思维脑图(技能树)】
知识不体系?这里还有整理出来的Android进阶学习的思维脑图,给大家参考一个方向。
[外链图片转存中…(img-F1jkcytZ-1645094067039)]
【Android高级架构视频学习资源】
**Android部分精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
Android 图片压缩之多种压缩方式结合使用,阿里Android开发面试解答相关推荐
- Android图片视频拍摄选取及压缩
Android图片视频选取及压缩上传 此博客的主要技术点 需求 开车了 图片选择库 视频压缩 上传 此博客的主要技术点 视频拍摄.视频选取获取视频地址 视频压缩 视频上传 需求 我的项目1.0版本最近 ...
- Android 图片压缩之多种压缩方式结合使用
原文地址:http://www.jianshu.com/p/e9e1db845c21 如题,多种压缩方式常用的有尺寸压缩.质量压缩以及通过JNI调用libjpeg库来进行压缩,三种方式结合使用实现指定 ...
- android图片选择器框架支持长图,基于RxJava的Android图片选择器. – RxPicker
RxPicker 基于 RxJava 的 Android 图片选择器. 特性 与 RxJava 结合,支持响应式得到选择图片结果 兼容 Android 7.0 自定义 ImageLoader 预览 使 ...
- 2022中级Android开发面试解答,当上项目经理才知道
缘起 随着互联网企业的不断发展,产品项目中的模块越来越多,用户体验要求也越来越高,想实现小步快跑.快速迭代的目的越来越难,还有65535,应用之间的互相调用等等问题,插件化技术应用而生.如果没有插件化 ...
- android 图片方法,分享实现Android图片选择的两种方式
Android选择图片的两种方式: 第一种:单张选取 通过隐式启动activity,跳转到相册选择一张返回结果 关键代码如下: 发送请求: private static final int PICTU ...
- 通过纯css实现图片居中的多种实现方式
html结构: 1 <div class="demo" style="width: 800px;height: 600px; border:1px solid #d ...
- android期末考试选择题,轻松拿到了阿里Android高级开发工程师的offer
前言 在这个网络发展快速的时代,我想问为什么你选择做程序员?有人说因为不善交际,也有人说最火的行业互联网,最好的职业程序员.确实在这个繁荣的行业,只要你自己不下船技术不水,就可以衣食无忧,努力努力说不 ...
- Android 图片压缩各种方式
前言:由于公司项目当中需要用到压缩这块的相应技术,之前也做过的图片压缩都不是特别的理想, 所以这次花了很多心思,仔细研究和在网上找到了很多相对应的资料.为了就是 以后再做的时候直接拿来用就可以了! 第 ...
- android图片压缩的三种方式
为了避免oom的出现,几乎每个应用都会对大图进行压缩,我现在手头做的产品就有很多地方用到,以前封装工具类的时候,都是在网上找东找西,然后拼拼凑凑,有效果就行了,一直用的迷迷糊糊,这几天工作比较闲,正好 ...
最新文章
- 史上最全的“大数据”学习资源
- C 关于页面刷新和combobox的使用
- 复制订阅服务器和 AlwaysOn 可用性组 (SQL Server)
- 为什么百万医疗险越来越多,到底选哪款?
- 兼容多种屏幕分辨率的通栏大图实现方法
- iptables 范例
- linux fedora35让GRUB 2记住上一次启动的操作系统
- ASP.NET Core Cookie SameSite
- 编程 ul 不能一行显示 跳到下行_史上最全的数控G代码编程详解
- Android4.0源码目录结构详解
- 淘宝用户行为分析(python+mysql+tableau)
- 解决Python爬取百度页面出现中文乱码问题
- 9 个将改变一切的物联网应用
- 论文解读:Making Pre-trained Language Models Better Few-shot Learners(LM-BFF)
- Typora如何把图片上传到图床smms.app
- 电影: 嘲笑过片名后,我哭着看完这部片
- 关于实现校园网防断网的可行方案
- 使用图像处理技术去除图片水印
- 微营销软件需要的计算机技术,WeTool 一款专用于个人微信营销操作及运营的电脑工具...
- 技术中台建设方法和关键设计