Android Camera 即時濾鏡(四),androidcamera
基於Android平台PS特效的自訂演算法的實現Created with Raphaël 2.1.2開始映像Bitmap擷取像素getPixelsPS演算法 修改像素點Color.red/green/blue濾鏡映像結束
在ARGB色彩空間,分別使用A(Transparency)、R(Red)、G(Green)、B(Blue)四個值來描述一個像素點,那麼對於一個寬w高h的圖片來說,共有w*h個像素點,可以用一個數組對象int [] pixels來表示相應的圖片,pixels = { p1,p2,p3…}。在把各個像素點都用ARGB來表示,那麼這張圖片就可以用一個[w*h,4]的矩陣來描述:
pixels = { pa1,pr1,pg1,pb1, pa2,pr2,pg2,pb2, pa3,pr3,pg3,pb3, ……}
android平台在擷取像素方面提供了 Bitmap.getPixels 方法,我需要做的是遍曆映像的像素點,對每一個像素點進行計算。然後將計算完的像素點通過Color.red/green/blue 方法處理後,將像素點填回Bitmap,從而得到濾鏡後的映像。這種方式比ColorMatrix 要靈活,可以滿足PS特效的實現效果。
1、簡單的反色濾鏡實現
取出圖片的像素點,然後用255減去每個像素點,那麼得到的就是一張有反色效果的圖片
演算法如下:
/** * @author neil */public class AntiColorFilter implements ImageFilterInterface { private ImageData image = null; // 圖片資訊類 public AntiColorFilter(Bitmap bmp) { image = new ImageData(bmp); } public ImageData imageProcess() { int width = image.getWidth(); int height = image.getHeight(); int R, G, B, pixel; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { R = image.getRComponent(x, y); // 擷取RGB三原色 G = image.getGComponent(x, y); B = image.getBComponent(x, y); R = 255 - R; B = 255 - B; G = 255 - G; image.setPixelColor(x, y, R, G, B); } // x } // y return image; }}
2、油畫濾鏡的實現
通過查資料瞭解到油畫濾鏡的演算法是”用當前點四周一定範圍內任意一點的顏色來替代當前點顏色,最常用的是隨機的採用相鄰點進行替代”
演算法如下:
public ImageData imageProcess() { int width = image.getWidth(); int height = image.getHeight(); int R, G, B, pixel,xx = 0,yy = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int pos = getRandomInt(1, 10000) % Model; xx = (x + pos) < width ? (x + pos) : (x - pos) >= 0 ? (x - pos) : x; yy = (y + pos) < height ? (y + pos) : (y - pos) >= 0 ? (y - pos) : y; R = image.getRComponent(xx, yy); // 擷取RGB三原色 G = image.getGComponent(xx, yy); B = image.getBComponent(xx, yy); image.setPixelColor(x, y, R, G, B); } // x } // y return image; } public static int getRandomInt(int a, int b) { int min = Math.min(a, b); int max = Math.max(a, b); return min + (int)(Math.random() * (max - min + 1)); }
3、冰凍濾鏡的實現
冰凍濾鏡的演算法是將像素點顏色加深,每個象素都用RGB三原色來表示,(0,0,0)就是純黑,而(255,255,255)就是純白,因此將沒個像素點的RGB指變小,顏色就會加深
int width = image.getWidth(); int height = image.getHeight(); int R, G, B, pixel; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { R = image.getRComponent(x, y); // 擷取RGB三原色 G = image.getGComponent(x, y); B = image.getBComponent(x, y); pixel = R - G - B; pixel = pixel * 3 / 2; if (pixel < 0) pixel = -pixel; if (pixel > 255) pixel = 255; R = pixel; pixel = G - B - R; pixel = pixel * 3 / 2; if (pixel < 0) pixel = -pixel; if (pixel > 255) pixel = 255; G = pixel; pixel = B - R - G; pixel = pixel * 3 / 2; if (pixel < 0) pixel = -pixel; if (pixel > 255) pixel = 255; B = pixel; image.setPixelColor(x, y, R, G, B); } // x } // y