濾鏡
濾鏡;主要是用來實現圖像的各類特殊效果。它在Photoshop中具備很是神奇的做用。濾鏡一般須要同通道、圖層等聯合使用,才能取得最佳藝術效果。java
在移動端或者在web開發時處理圖片都是一件麻煩的事兒。我調研過不少library,特別是在移動端處理圖片時動不動都須要使用 C++ 或者 OpenCV。這對於 Java 程序員來講,具備很高的門檻。甚至在調試時,遇到錯誤都會沒法下手進行處理。其實,隨着手機設備性能的不斷提升,使用 Java 一樣能完成這些事情。android
實現
這是原圖,能夠選擇濾鏡來美化圖片。git
![](http://static.javashuo.com/static/loading.gif)
這是幾種濾鏡的效果程序員
![](http://static.javashuo.com/static/loading.gif)
首先,咱們的庫叫 cv4j,cv 是 Computer Vision 的意思,同時也用於致敬 OpenCV。
https://github.com/imageprocessor/cv4jgithub
以SepiaTone濾鏡爲例,咱們本身私下叫它懷舊風格的濾鏡web
![](http://static.javashuo.com/static/loading.gif)
import com.cv4j.core.datamodel.ImageData; import com.cv4j.image.util.Tools; public class SepiaToneFilter implements CommonFilter { @Override public ImageData filter(ImageData src) { int width = src.getWidth(); int height = src.getHeight(); int offset = 0; for(int row=0; row<height; row++) { offset = row * width; int tr = 0, tg = 0, tb = 0; for (int col = 0; col < width; col++) { tr = (src.getPixels()[offset] >> 16) & 0xff; tg = (src.getPixels()[offset] >> 8) & 0xff; tb = src.getPixels()[offset] & 0xff; int fr = (int) colorBlend(noise(), (tr * 0.393) + (tg * 0.769) + (tb * 0.189), tr); int fg = (int) colorBlend(noise(), (tr * 0.349) + (tg * 0.686) + (tb * 0.168), tg); int fb = (int) colorBlend(noise(), (tr * 0.272) + (tg * 0.534) + (tb * 0.131), tb); src.getPixels()[offset] = (255 << 24) | (Tools.clamp(fr) << 16) | (Tools.clamp(fg) << 8) | Tools.clamp(fb); offset++; } } return src; } private double noise() { return Math.random()*0.5 + 0.5; } private double colorBlend(double scale, double dest, double src) { return (scale * dest + (1.0 - scale) * src); } }
ImageData是咱們本身定義的圖像數據結構。全部的濾鏡都是經過ImageData來傳遞。算法
import android.graphics.Bitmap; public interface ImageData { int CV4J_IMAGE_TYPE_RGB = 0; int CV4J_IMAGE_TYPE_GRAY = 2; int CV4J_IMAGE_TYPE_HSV = 4; int CV4J_IMAGE_TYPE_BINARY = 8; int[] getPixels(); int getWidth(); int getHeight(); int getType(); byte[] getChannel(int index); void putPixels(int[] pixels); int getPixel(int row, int col); void setPixel(int row, int col, int rgb); int[] getPixelByRowNumber(int rowIndex); void convert2Gray(); Bitmap toBitmap(); }
ImageData是一個接口,目前它的實現類只有ColorImage。
因此使用一個濾鏡,一般只要這樣寫的就ok了。數據結構
ColorImage colorImage = new ColorImage(bitmap); CommonFilter filter = new SepiaToneFilter(); colorImage = (ColorImage) filter.filter(colorImage); imageView.setImageBitmap(colorImage.toBitmap());
性能是咱們一直關心的話題,我在模擬器上跑了demo app,經過 AOP 的方法打印了 demo app 中一些濾鏡在使用時花費的時間。架構
![](http://static.javashuo.com/static/loading.gif)
在demo app中,濾鏡實例化是藉助Class.forName()確定比直接使用new 某個濾鏡類要慢一些。app
![](http://static.javashuo.com/static/loading.gif)
總結
cv4j 是賈志剛和我一塊兒開發的圖像處理庫,目前還處於很早期的版本。咱們天天都會對這個庫作一些提交。整個庫在架構上和圖像算法上都還有很大的提高空間。
本文同步分享在 博客「fengzhizi715」(JianShu)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。