android图片缩放,Android 图片压缩

Android自定义控件之可平移、缩放、旋转图片控件

先上效果图

让客户满意是我们工作的目标,不断超越客户的期望值来自于我们对这个行业的热爱。我们立志把好的技术通过有效、简单的方式提供给客户,将通过不懈努力成为客户在信息化领域值得信任、有价值的长期合作伙伴,公司提供的服务项目有:域名与空间、虚拟主机、营销软件、网站建设、景洪网站维护、网站推广。

源码

单点拖动图片对图片进行平移操作。双手缩放图片大小和旋转图片到一定的角度。图片缩放的时候 不能大于最大的缩放因子和小于最小的缩放因子。大于最大缩放因子或者小于最小缩放因子需要对图像进行回弹。图片旋转的角度只能为90度的倍数,不满足90度要进行回弹。图片回弹要一个渐变的效果。

大体思路: 首先,Android中提供了Matrix类可以对图像进行处理。其次,要显示一张图片最容易想到的就是ImageView。回弹要求渐变的过程,可以通过属性动画进行设置。所以大体的思路是:继承ImageView,重写onTouchEvent()方法,判断事件类型,在对应的事件使用Matrix对图像进行变换。

Matrix是一个已经封装好的矩阵,最重要的作用就是对坐标点进行变换。

举个栗子:

1.某个点(x0,y0,1)通过单位矩阵E映射得到的点还是(x0,y0,1)。

3.点(x0,y0,1)通过矩阵T映射得到的点就会做如下的变换

可以看到点(x0,y0,1)经过T矩阵在x轴方向上平移了dx,在y轴方向上平移了dy。

通过以上的变换可以得到具体的思路: 我们维护一个图像对应的矩阵mCurrentMatrix,该矩阵主要是对ImageView中的图像的各个点进行映射。ImageView在容器位置摆放完成之后,置mCurrentMatrix矩阵为单位矩阵。当onTouchEvent()方法中触发单点触控并且手指进行平移的时候,调用矩阵mCurrentMatrix的postTranslate(dx,dy),对mCurrentMatrix进行变换。当手指抬起,利用变换结束后的矩阵对图像的各个点进行映射,从而得到平移变换后的图像。同理可得,在两只手指进行缩放旋转的时候,我们对矩阵mCurrentMatrix进行各种变换,当缩放旋转的事件结束再利用变换完的矩阵去映射图像的各个点,从而得到缩放、旋转后的图像。

安卓自定义View进阶 - Matrix原理

安卓自定义View进阶 - Matrix详解

首先理清事件的逻辑:

初始化图像大小和位置

缩放图像大小和控件大小自适应,平移图像中心和控件中心重合

onTouchEvent()函数

平移操作

将图像对应的矩阵进行变换。

缩放操作

mBoundRectF为记录图像边界的矩形。缩放的时候选取图像的中心进行缩放。

旋转操作

旋转的时候旋转的旋转中心也是图像的中心

图像中各个点的映射

调用ImageView的setImageMatrix(Matrix matrix)会让ImageView根据设置的matrix去重新绘制图像。

更新图像的矩形边界

获得图像的矩形,并根据矩阵映射矩形各个点的坐标。

缩放回弹

旋转回弹

一些计算方法

要求图像的变换是一个渐变的过程,很容易想到的就是属性动画。因为属性动画本身就是对值进行不断set的过程。而我们维护的矩阵也是一个值,所以很自然可以想到,如果得到回弹之前的矩阵的值以及回弹之后矩阵的值,就可以根据动画监听器中动画当前的系数值去改变矩阵的值。

对animator对象设置完监听器之后,就可以在手指抬起的时候调用属性动画的start()方法开启动画。

自定义可平移、缩放、旋转的控件主要点有两个方面:一是onTouchEvent()中判断平移、旋转、缩放的触发条件,平移位移量、缩放比例因子、旋转角度的计算。二是Matrix矩阵的应用。

android图片压缩避免OOM

简单吹下牛:很多app都会要加载图片,但是如果不压缩图片就很容易OOM,

个人看来OOM 出现原因总的来说分为两种:

一种是内存溢出(好像在扯淡,OOM本身就是内存溢出)

另一种是:图片过大,一个屏幕显示不完全造成,似乎也是一。。 如有错误纯属扯淡;

为了避免上面的情况:加载图片的时候可以进行压缩,上传的时候要可以进行压缩,在图片不可见的时候进行回收(onDetach()),再吹一句 用了fresco+压缩之后加载图片完全没问题了。

一、质量压缩方法:

privateBitmap compressImage(Bitmap image) {

ByteArrayOutputStream baos =newByteArrayOutputStream();

image.compress(Bitmap.CompressFormat.JPEG,100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中

intoptions =100;

while( baos.toByteArray().length /1024100) {//循环判断如果压缩后图片是否大于100kb,大于继续压缩

baos.reset();//重置baos即清空baos

image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中

options -=10;//每次都减少10

}

ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中

Bitmap bitmap = BitmapFactory.decodeStream(isBm,null,null);//把ByteArrayInputStream数据生成图片

returnbitmap;

}

二、图片按比例大小压缩方法(根据Bitmap图片压缩)

privateBitmap comp(Bitmap image) {

ByteArrayOutputStream baos =newByteArrayOutputStream();

image.compress(Bitmap.CompressFormat.JPEG,100, baos);

if( baos.toByteArray().length /10241024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出

baos.reset();//重置baos即清空baos

image.compress(Bitmap.CompressFormat.JPEG,50, baos);//这里压缩50%,把压缩后的数据存放到baos中

}

ByteArrayInputStream isBm =newByteArrayInputStream(baos.toByteArray());

BitmapFactory.Options newOpts =newBitmapFactory.Options();

//开始读入图片,此时把options.inJustDecodeBounds 设回true了

newOpts.inJustDecodeBounds =true;

Bitmap bitmap = BitmapFactory.decodeStream(isBm,null, newOpts);

newOpts.inJustDecodeBounds =false;

intw = newOpts.outWidth;

inth = newOpts.outHeight;

//现在主流手机比较多是800*480分辨率,所以高和宽我们设置为

floathh = 800f;//这里设置高度为800f

floatww = 480f;//这里设置宽度为480f

//缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可

intbe =1;//be=1表示不缩放

if(w  h  w  ww) {//如果宽度大的话根据宽度固定大小缩放

be = (int) (newOpts.outWidth / ww);

}elseif(w  h  h  hh) {//如果高度高的话根据宽度固定大小缩放

be = (int) (newOpts.outHeight / hh);

}

if(be =0)

be =1;

newOpts.inSampleSize = be;//设置缩放比例

//重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了

isBm =newByteArrayInputStream(baos.toByteArray());

bitmap = BitmapFactory.decodeStream(isBm,null, newOpts);

returncompressImage(bitmap);//压缩好比例大小后再进行质量压缩

}

说说在 Android 中如何压缩图片

1:ByteArrayOutputStream 压缩图片质量,不会改变图片大小

private Bitmap compressImage(Bitmap image) {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中

int options = 100;        while ( baos.toByteArray().length / 1024100) { //循环判断如果压缩后图片是否大于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;

}

2:就是改变图片大小

private Bitmap getimage(String srcPath) {

BitmapFactory.Options newOpts = new BitmapFactory.Options();        //开始读入图片,此时把options.inJustDecodeBounds 设回true了

newOpts.inJustDecodeBounds = true;

Bitmap bitmap = BitmapFactory.decodeFile(srcPath,newOpts);//此时返回bm为空

newOpts.inJustDecodeBounds = false;        int w = newOpts.outWidth;        int h = newOpts.outHeight;        //现在主流手机比较多是800*480分辨率,所以高和宽我们设置为

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了

bitmap = BitmapFactory.decodeFile(srcPath, newOpts);        return compressImage(bitmap);//压缩好比例大小后再进行质量压缩    }

android等比例缩放图片的方法

itmap icon = null;//原始图片

int width = icon.getWidth(), height = icon.getHeight();

float scaleRate = 0.8f;//缩小的比例

while(width = 300 || width = 300) {

Matrix matrix = new Matrix();

matrix.postScale(width * scaleRate, height * scaleRate);

// 得到新的图片

Bitmap newIcon = Bitmap.createBitmap(icon, 0, 0, width, height, matrix, true);

icon.recycle();

icon = newIcon;

width = icon.getWidth(), height = icon.getHeight();

}int width = icon.getWidth(), height = icon.getHeight();

if(width 300 || width 300) {

float scaleRate = width height ? 300 / width : 300 / height;

Matrix matrix = new Matrix();

matrix.postScale(width * scaleRate, height * scaleRate);

// 得到新的图片

Bitmap newIcon = Bitmap.createBitmap(icon, 0, 0, width, height, matrix, true);

icon.recycle();

icon = newIcon;

}

Android黑科技,图片终极压缩

一、支持自定义配置、不失真和批量处理

二、图片上传为什么要压缩

1、图片服务器空间限制,磁盘昂贵

2、网络不稳定,大文件需要断点续传

3、尽可能避免安卓OOM异常

4、后台约定的规则200KB

5、需要上传原图的应用有医院临床项目、金融银行

三、图片压缩流程

1、递归每张图片

2、设置图片格式 Bitmap.CompressFormat.JPG

png, jpg,webp

3、质量压缩bitmap.compress(format,quality,baos)

由于png是无损压缩,所以设置quality无效(不适合作为缩略图)

采样率压缩BitmapFactory.Options.inSampleSize

缩小图片分辨率,减少所占用磁盘空间和内存大小

缩放压缩canvas.drawBitmap(bitmap, null,rectF,null)

减少图片的像素,降低所占用磁盘空间大小和内存大小,可用于缓存缩略图

JNI调用JPEG库

Android的图片引擎使用的是阉割版的skia引擎,去掉了图片压缩中的哈夫曼算法

4、像素修复

5、返回压缩

6、完成压缩

demo:

参考:

Luban框架

缺点

1、当没有设定压缩路径时,抛异常无闪退

2、源码中,压缩比率固定值60,无法修改

3、压缩配置,参数不太适应真实项目需求

4、不能指定压缩大小,比如100KB以内


分享题目:android图片缩放,Android 图片压缩
文章出自:http://hbruida.cn/article/dscieop.html