1972年11月的《花花公子》杂志的封面人物名叫Lena Soderberg模特照片,成为数字图像处理和压缩的标准格式,研究人员用它来测试自己的算法,还常被用作数字视频处理各种实验及科学出版物的例图。
规避图片OOM或省流量及快速上传给后台。图片类社交App可选Fresco框架。
-- Android 图片压缩框架- https://github.com/Shouheng88/Compressor
Android 端的相机优化和 JNI 操作 OpenCV 进行图片处理
Luban 和 Compressor
-- ImageView.ScaleType
Android ImageView的scaleType属性与adjustViewBounds属性- http://www.2cto.com/kf/201411/348601.html
[Android] ImageView.ScaleType设置图解- http://blog.csdn.net/larryl2003/article/details/6919513
自定义ImageView控件 | 一个可以缩放, 平移的自定义ImageView控件- http://best.factj.com/sephiroth74/ImageViewZoom
-- com.bumptech.glide.request.target.SquaringDrawable cannot be cast to android.graphics.drawable.Bitma- https://blog.csdn.net/onceing/article/details/73277016
Glide.with(getContext()).load(R.drawable.com_ic_default_avatar_home)
.asBitmap().into(mPersionImage);
-- Xfermode
图像操纵大师Xfermode:自定义UI中,少不了对多种图像的叠加覆盖,而需要达到预期的目的,我们便需要今天的主角Xfermode。Xfermode 有三个孩子,分别是:AvoidXfermode ,PixelXorXfermode ,PorterDuffXfermode;而 AvoidXfermode 和 PixelXorXfermode 已经在 API 16之后被标记为removed,所以就只剩下小儿子 PorterDuffXfermode 为我们合成图像;
https://github.com/zincPower/UI2018/blob/master/class4_xfermode/src/main/java/com/zinc/class4_xfermode/widget/GoogleXFerModeView.java
https://github.com/zincPower/UI2018/blob/master/class4_xfermode/src/main/java/com/zinc/class4_xfermode/activity/ZincXFerModeActivity.java
> 图片压缩、处理,Gif,大图
-- 图片压缩
在 Android 中进行图片压缩是非常常见的开发场景,主要的压缩方法有两种:其一是质量压缩,其二是下采样压缩。
如何提高 Android 的压缩率,这里需要提到两个库,一个是 mozilla/mozjpeg,另一个是 libjpeg-turbo,前者是一个来自 Mozilla 实验室的 JPEG 图像编码器项目,目标是在不降低图像质量且兼容主流的解码器的情况下,提供产品级的 JPEG 格式编码器来提高压缩率以减小 JPEG 文件的大小,后者相当于是一个 libjpeg 的增强版,前者也是基于后者,在后者的基础上进行了一些优化。
第三方编码解码库或者硬件编解码库,例如 libpng 和 libjpeg,libgif 等.
libjpeg是广泛使用的开源JPEG图像库(http://en.wikipedia.org/wiki/Libjpeg ),安卓也依赖libjpeg来压缩图片。通过查看源码,我们会发现安卓并不是直接封装的libjpeg,而是基于了另一个叫Skia的开源项目(http://en.wikipedia.org/wiki/Skia_Graphics_Engine)来作为的图像处理引擎。Skia是谷歌自己维护着的一个大而全的引擎,各种图像处理功能均在其中予以实现,并且广泛的应用于谷歌自己和其它公司的产品中(如:Chrome、Firefox、Android等)。Skia对libjpeg进行了良好的封装,基于这个引擎可以很方便为操作系统、浏览器等开发图像处理功能。libjpeg在压缩图像时,有一个参数叫optimize_coding。压缩工具及原理:tinypng ,pngquant。
基于libjpeg-turbo自行编译了一版native的安卓库,专门用来压缩图片-https://github.com/bither
JNI实现图片压缩- https://github.com/zengfw/EffectiveBitmap
Android图片压缩- https://github.com/bither/bither-android-lib
Android图片压缩- http://download.csdn.net/detail/loveroselove/9495382
Tiny图片压缩库- https://github.com/Sunzxyong/Tiny
bitmap的六种压缩方式,Android图片压缩- http://blog.csdn.net/harryweasley/article/details/51955467
图片压缩Compressor- https://github.com/zetbaitsu/Compressor
针对图片尺寸的修改其实就是一个图像重新采样的过程,放大图像称为上采样(upsamping),缩小图像称为下采样(downsampling).
在 Android 中图片重采样提供了两种方法,一种叫做邻近采样(Nearest Neighbour Resampling),另一种叫做双线性采样(Bilinear Resampling)。
除了 Android 中这两种常用的重采样方法之外,还有另外比较常见的两种:双立方/双三次采样(Bicubic Resampling) 和 Lanczos Resampling。除此之外,还有一些其他个人或机构发明的算法 Hermite Resampling,Bell Resampling,Mitchell Resampling。
-- 图片无损压缩:ImageOptim ; 图片有损压缩:TinyPNG/ImageAlpha
TinyPNG支持对 PNG/JPEG 文件做压缩处理,效果不错- https://tinypng.com/
pngquant支持 PNG 压缩,有时候 TinyPNG 处理过的图片噪点会稍多,可以考虑用 pngquant 来处理- https://pngquant.org/
ImageOptim支持压缩 PNG/JPEG/GIF,只支持 Mac- https://imageoptim.com/mac
mozjpeg:ImageOptim online用于 PNG 转 JPEG、JPEG 压缩- https://imageoptim.com/online
-- 图像处理
图像处理技术- https://blog.csdn.net/jinshengtao/article/category/2776655
Android开发常用开源框架:图片处理- http://blog.csdn.net/axi295309066/article/details/56984137
Android图像处理整理- http://blog.csdn.net/luzhenyuxfcy/article/details/49427781
人们普遍认为角点是二维图像亮度变化剧烈的点或图像边缘曲线上曲率极大值的点。
角点的检测主要有两类基于图像边缘的方法和基于图像灰度的方法。前者很大程度上依赖于图像的分割和边缘提取,一旦待检测目标发生局部变化,很可能导致操作失败,因此该类方法使用范围较小;后者有很多方法,包括Harris算子,Moravec算子,Susan算子等等。
两个图像处理库:libjpeg、Skia。
Android多点触控技术实战,自由地对图片进行缩放和移动- http://blog.csdn.net/guolin_blog/article/details/11100327
PinchImageView(http://best.factj.com/boycy815/PinchImageView)|国人写的, 可能是体验最好的图片手势控件| 支持双击放大,双击缩小,超出边界会回弹, 滑动惯性,不同分辨率无缝切换,可与ViewPager结合使用。
GestureViews(http://best.factj.com/alexvasilkov/GestureViews)|包含ImageView的自定义FrameLayout | 项目目的是让图片的查看尽可能流畅平滑, 让开发者更加方便地集成到自己的应用中, 支持手势控制和动画 。
PhotoView(http://best.factj.com/chrisbanes/PhotoView)| 致力于帮助开发者高效的创建可缩放的ImageView | 重写ImageView的实现, 支持多点触摸的图片缩放
subsampling-scale-image-view(http://best.factj.com/davemorrissey/subsampling-scale-image-view) | 一个Android自定义图片视图, 专为图片画廊设计| 丰富的配置选项, 更方便的实现图片的手势缩放, 旋转, 平移. 无损展示大图, 完美的地嵌入画廊, 地图等.可显示大图(地图, 建筑设计图)等而不造成OutOfMemoryErrors(OOM内存溢出异常)
TouchImageView(http://best.factj.com/MikeOrtiz/TouchImageView) | 一个ImageView的拓展类 | 支持ImageView所有功能, 添加了平移, 缩放, 拖拽, 滑动, 双击缩放等动画.
Android图片剪裁库- https://github.com/Jhuster/ImageCropper
圆形图标制作Image Asset Studio- https://github.com/baidusoso/RoundIcon
Android图片选择框架,提供了微信和知乎主题的UI支持- https://github.com/qingmei2/RxImagePicker
Android 端强大的仿微信图片选择器- https://gitee.com/maxiaoyong/Multi_image_selector_from_Github
自定义图片九宫格控件(IKNinePhotoView)- https://github.com/Idtk/IKNinePhotoView
- Tiny Jpeg Decoder (JPEG解码)
Tiny Jpeg Decoder是一个可以用于嵌入式系统的JPEG解码器。也可以在Windows上编译通过。在此分析一下它部分的源代码,辅助学习JPEG解码知识。通过TinyJpeg可以将JPEG(*.jpg)文件解码为YUV(*.yuv)或者RGB(*.tga)文件。
- ImageMagik处理图片的功能很强大 vs PhotoShop。ImageMagick是一套功能强大、稳定而且开源的工具集和开发包,可以用来读、写和处理超过89种基本格式的图片文件,包括流行的TIFF、JPEG、GIF、PNG等格式。利用ImageMagick,你可以根据web应用程序的需要动态生成图片, 还可以对一个(或一组)图片进行改变大小、旋转、锐化、减色或增加特效等操作,并将操作的结果以相同格式或其它格式保存,对图片的操作,即可以通过命令行进行,也可以用C/C++、Perl、Java、PHP、Python或Ruby编程来完成。
-- # 腾讯WebP图片的探索,大致的示例代码
InputStream is = getAssets().open("weixin.webp");
Bitmap bitmap = null;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
bitmap = WebPDecoder.getInstance().decodeWebP(streamToBytes(is));
} else {
bitmap = BitmapFactory.decodeStream(is);
}
imageView.setImageBitmap(bitmap);
private static byte[] streamToBytes(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream(1024);
byte[] buffer = new byte[1024];
int len;
try {
while ((len = is.read(buffer)) >= 0) {
os.write(buffer, 0, len);
}
} catch (java.io.IOException e) {
}
return os.toByteArray();
}
-- 加载巨图方案(制作长图及加载长图)
Android 高清加载巨图方案 拒绝压缩图片- http://blog.csdn.net/trent1985/article/details/49332877
很多的手势检测- https://github.com/rharter/android-gesture-detectors
显示巨图的方案- https://github.com/johnnylambada/WorldMap
Android大图片处理- http://blog.csdn.net/geofferysun/article/details/52805619
-- 制作/播放GIf Android (Glide)
glide可以支持gif和短视频。
Android实现播放GIF动画的强大ImageView- http://www.cnblogs.com/qingchen1984/p/5056390.html
Android屏幕内容制作成GIF图方式- http://blog.csdn.net/u014686875/article/details/51124969
android app动图优化:源码giflib加载gif动图,性能秒杀glide- https://blog.csdn.net/wxk105/article/details/71698515
GIF动态图制作- http://blog.csdn.net/q4878802/article/details/49274557
> 其他Android图片压缩开源库Demo
Luban(鲁班) —— Android图片压缩工具,仿微信朋友圈压缩策略。
Android 图片压缩LuBan鲁班eclipse版项目- http://download.csdn.net/detail/pengpenggxp/9828742
图片压缩LuBan demo- http://download.csdn.net/detail/shareus/9853438
Luban - https://github.com/Curzibn/Luban
Google 官方多媒体和图形图像相关的处理:https://github.com/google/grafika
> 图片处理中的软引用、强化引用、弱引用;三级缓存策略
在内存引用上做些处理,常用的有软引用、强化引用、弱引用(如图片处理)。
在过去,我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,这就有潜在的风险造成应用程序的内存溢出并崩溃。
软引用(SoftReference)、虚引用(PhantomRefrence)、弱引用(WeakReference),这三个类是对heap中java对象的应用
heap中对象有强可及对象、软可及对象、弱可及对象、虚可及对象和不可到达对象。应用的强弱顺序是强、软、弱、和虚。对于对象是属于哪种可及的对象,由他的最强的引用决定。
String abc=new String("abc"); //1、强可及对象
SoftReference<String> abcSoftRef=new SoftReference<String>(abc); //2、软可及对象
WeakReference<String> abcWeakRef = new WeakReference<String>(abc); //3、弱可及对象
Object obj = new Object();
PhantomReference<Object> pf = new PhantomReference<Object>(obj); //4、虚可及对象 abc=null;
abcSoftRef.clear();//5、不可到达对象
-- 三级缓存策略,内存 硬盘策略及占用大小及限制. 图片缓存技术
图片的三级缓存机制一般是指应用加载图片的时候,分别去访问内存,文件和网络而获取图片数据的一种行为。缓存策略,采用“内存-本地-网络”三级缓存策略:
1.内存缓存使用的就是LruCache.
2.文件缓存,我们使用的是DiskLruCache
3.网络请求,这里我们使用Volley网络请求框架。
> 开源图片处理框架,Picasso/Glide/ImagLoader/Fresco
图片加载库:ImageLoader,UIL,Volley,主流的有,Picasso,Glide,Fresco
-- 图片处理
Picasso-transformations 一个为Picasso提供多种图片变换的库;
Glide-transformations 一个为Glide提供多种图片变换的库;
Android-gpuimage,基于OpenGL的Android过滤器;
1.Picasso是著名的开源组织Square出品的图片处理框架,使用的比较多;
2.Glide是Google的员工基于Picasso开发,优化的,Android官网推荐使用的图片处理框架;
3.Fresco是Facebook开源的图片处理框架,真正做到了三级缓存,功能强大,强烈推荐使用;
4.Android Universal Image Loader是一个老牌的图片处理框架,但是在2015年的9月份已经停止更新维护,所以不推荐使用。
说到内存缓存的实现,非常容易就让人想到LruCache算法(Least Recently Used),也叫近期最少使用算法。它的主要算法原理就是把最近使用的对象用强引用存储在LinkedHashMap中,并且把最近最少使用的对象在缓存值达到预设定值之前从内存中移除。LruCache的用法也比较简单.
Glide内存缓存的实现自然也是使用的LruCache算法。不过除了LruCache算法之外,Glide还结合了一种弱引用的机制,共同完成了内存缓存功能
Android图片加载框架最全解析(三),深入探究Glide的缓存机制- http://blog.csdn.net/guolin_blog/article/details/54895665
Picasso,Glide,Fresco对比分析- http://blog.csdn.net/github_33304260/article/details/70213300
Picasso框架:获取并显示远程图片,强大的图片下载和缓存的第三方库。
Picasso的基本用法:Picasso.with(context).load(imageUrl).into(imageView);
剪裁大小:Picasso.with(context).load(imageUrl).resize(50,50).centerCrop().into(imageView);
占位符图片:Picasso.with(context).load(imageUrl).placeholder(R.drawable.image_placeholder).error(R.drawable.image_error_placeholder);
载入本地资源:Picasso.with(context).load(R.drawable.icon).into(imageView);
Picasso.with(context).load("file:///android_asset/Adnroid.png").into(imageView);
Picasso.wiht(context).load(new File(...)).into(imageView);
调试:为了方便调试,可以通过调用Picasso的setIndicatiorEnabled(true);可以让不同来源的图片显示一个不同的色彩标记.
解决问题:
自动将图像缓存在本地;通过图片压缩转换以减少内存消耗;自动处理了ImageView的回收,即自动取消不在视野范围内的ImageView视图资源的加载;在适配器中自动发现和重用以前取消的下载;图像格式转换:很多时候需要将图片进行格式转换或者剪裁以节省内存或者达到我们的布局效果;占位符图片:当图片未正常显示时默认的图片,通过placeholder()设置,Picasso也支持设置图片显示错误时显示的默认图片,通过error()设置;
设置图片圆角: 步骤1:
public class CircleTransform implements Transformation {
@Override
public Bitmap transform(Bitmap source) {
int size = Math.min(source.getWidth(), source.getHeight());
int x = (source.getWidth() - size) / 2;
int y = (source.getHeight() - size) / 2;
Bitmap squaredBitmap = Bitmap
.createBitmap(source, x, y, size, size);
if (squaredBitmap != source) {
source.recycle();
}
Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
Canvas canvas = new Canvas(bitmap);
Paint paint = new Paint();
BitmapShader shader = new BitmapShader(squaredBitmap,
BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP);
paint.setShader(shader);
paint.setAntiAlias(true);
float r = size / 2f;
canvas.drawCircle(r, r, r, paint);
squaredBitmap.recycle();
return bitmap;
}
@Override
public String key() {
return "circle";
}
}
步骤2: Picasso.with(this).load(R.drawable.meinv2).transform(new CircleTransform()).into(img);
-- 1.Bugs:
com.bumptech.glide.request.target.SquaringDrawable cannot be cast to android.graphics.drawable.BitmapDrawable:
Android 关于Glide的拓展(高斯模糊、加载监听、圆角图片)- http://blog.csdn.net/onceing/article/details/73277079
-- 2.Bugs: Picasso detected an unsupported OkHttp on the classpath- https://stackoverflow.com/questions/24125856/picasso-detected-an-unsupported-okhttp-on-the-classpath/32091981#32091981
解决方案(增加依赖包):
compile 'com.squareup.okhttp:okhttp:2.4.0'
compile 'com.squareup.okhttp:okhttp-urlconnection:2.2.0'
compile 'com.squareup.picasso:picasso:2.4.0'
--3.Error “You must not call setTag() on a view Glide is targeting” when use Glide - http://blog.csdn.net/ltym2014/article/details/51558695
报错原因大致是因为Glide加载的ImageView调用了setTag()方法导致的错误,因为Glide已经默认为ImageView设置的Tag。
解决办法:1.自定义一个Application,在里面加上
public class App extends Application {
@Override public void onCreate() {
super.onCreate();
ViewTarget.setTagId(R.id.glide_tag);
}
}
2.然后在/values/ids.xml加上
<resources>
<item type="id" name="glide_tag" />
</resources>
> 马赛克图与算法:
1. public class PixelateUtil {
/
普通图像->像素图,zoneWidth为像素图的大像素的宽度
/
public static Bitmap pixelate(Bitmap bitmap, int zoneWidth) {
return pixelate(bitmap, zoneWidth, 0, 0, bitmap.getWidth(), bitmap.getHeight());
}
/
普通图->像素图,left、top、right、bottom可指定打马赛克区域
/
public static Bitmap pixelate(Bitmap bitmap, int zoneWidth, int left, int top, int right, int bottom) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Bitmap result = bitmap.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(result);
Paint paint = new Paint();
for (int i = left; i < right; i += zoneWidth) {
for (int j = top; j < bottom; j += zoneWidth) {
int color = bitmap.getPixel(i, j);
paint.setColor(color);
int gridRight = Math.min(w, i + zoneWidth);
int gridBottom = Math.min(h, j + zoneWidth);
canvas.drawRect(i, j, gridRight, gridBottom, paint);
}
}
return result;
}
}
Bitmap result = PixelateUtil.pixelate(bitmap, zoneWidth); //对全图打马赛克
Bitmap result = PixelateUtil.pixelate(bitmap, zoneWidth, left, top, right, bottom); //对指定区域打马赛克
2. Pixelate是实现基本马赛克效果的开源项目,它能够异步对整个或者部分的Bitmap区域打马赛克,处理完后会在OnPixelateListener的onPixelated()中回调,最小的SDK版本为16。
Simple Android library to pixelate images or certain areas of an image- https://github.com/DanielMartinus/Pixelate
new Pixelate(origin)
.setArea(0,0,origin.getWidth(),origin.getHeight()) //设置区域
.setDensity(12) //值越大,马赛克单元越小
.setListener(new OnPixelateListener() {
@Override
public void onPixelated(Bitmap bitmap, int density) {
//bitmap为马赛克图
Log.v(TAG, "");
}
})
.make();
3. android-close-pixelate能够实现多样式的马赛克效果- https://github.com/bmaslakov/android-close-pixelate
Bitmap pixelated = Pixelate.fromBitmap(
origin,
new PixelateLayer.Builder(PixelateLayer.Shape.Circle) //设置马赛克形状
.setResolution(30) //每个像素的密度(如果该值和size值一样,那么圆形之间相邻)
.setSize(30) //圆圈的大小
.build()
);