近期项目中牵涉到图片滤镜效果,看了些大神们的资料,在这总结下,希望对大家也用帮助。
黑白效果:
// 黑白
public static Bitmap convertToBlackWhite(Bitmap bmp) {
if (bmp == null) {
return null;
}
int width = bmp.getWidth(); // 获取位图的宽
int height = bmp.getHeight(); // 获取位图的高
int[] pixels = new int[width * height]; // 通过位图的大小创建像素点数组
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int alpha = 0xFF << 24;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
int grey = pixels[width * i + j];
int red = ((grey & 0x00FF0000) >> 16);
int green = ((grey & 0x0000FF00) >> 8);
int blue = (grey & 0x000000FF);
grey = (int) (red * 0.3 + green * 0.59 + blue * 0.11);
grey = alpha | (grey << 16) | (grey << 8) | grey;
pixels[width * i + j] = grey;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
浅褐色效果:
// 浅褐色
public static Bitmap oldRemeber(Bitmap bmp) {
if (bmp == null) {
return null;
}
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
int pixColor = 0;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
pixColor = pixels[width * i + j];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = (int) (0.393 * pixR + 0.769 * pixG + 0.189 * pixB);
newG = (int) (0.349 * pixR + 0.686 * pixG + 0.168 * pixB);
newB = (int) (0.272 * pixR + 0.534 * pixG + 0.131 * pixB);
int newColor = Color.argb(255, newR > 255 ? 255 : newR,
newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
pixels[width * i + j] = newColor;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
浅绿色效果:
// 浅绿色
public static Bitmap greenRemeber(Bitmap bmp) {
if (bmp == null) {
return null;
}
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
int pixColor = 0;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
pixColor = pixels[width * i + j];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = (int) (0.122 * pixR + 0.769 * pixG + 0.123 * pixB);
newG = (int) (0.349 * pixR + 0.856 * pixG + 0.168 * pixB);
newB = (int) (0.110 * pixR + 0.534 * pixG + 0.120 * pixB);
int newColor = Color.argb(255, newR > 255 ? 255 : newR,
newG > 255 ? 255 : newG, newB > 255 ? 255 : newB);
pixels[width * i + j] = newColor;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
大家仔细观察下就会看出newR,newG,newB的值发生变化颜色也跟着变化,所以说还有多的颜色等着我们去试着改变就会有很多我们易想不到的滤镜。
底片效果:
// 底片色
public static Bitmap film(Bitmap bmp) {
if (bmp == null) {
return null;
}
final int MAX_VALUE = 255;
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for (int i = 1, length = height - 1; i < length; i++) {
for (int j = 1, len = width - 1; j < len; j++) {
pos = i * width + j;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = MAX_VALUE - pixR;
newG = MAX_VALUE - pixG;
newB = MAX_VALUE - pixB;
newR = Math.min(MAX_VALUE, Math.max(0, newR));
newG = Math.min(MAX_VALUE, Math.max(0, newG));
newB = Math.min(MAX_VALUE, Math.max(0, newB));
pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
浮雕效果:
// 浮雕
private Bitmap film(Bitmap bmp){
final int MAX_VALUE = 255;
int width = bmp.getWidth;
int height = bmp.getHeight;
Bitmap bitmap = bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int [width*height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for(int i = 1, length = height - 1; i < length; i++){
for(int k = 1, len = width - 1; k < len; k++){
pos = i * width + k;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
pixColor = pixels[pos + 1];
newR = Color.red(pixColor) - pixR + 127;
newG = Color.green(pixColor) - pixG + 127;
newB = Color.blue(pixColor) - pixB + 127;
newR = Math.min(MAX_VALUE, Math.max(0, newR);
newG = Math.min(MAX_VALUE, Math.max(0, newG);
newB = Math.min(MAX_VALUE, Math.max(0, newB);
pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
底片效果,和浮雕效果newR,newG,newB的值比较固定。不能改变,直接使用就行了。
光晕效果:
// 光照效果
private Bitmap sunshine(Bitmap bmp){
int width = bmp.getWidth;
int height = bmp.getHeight;
Bitmap bitmap = bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int centerX = width / 2;
int centerY = height / 2;
int radius = Math.min(centerX,centerY);
final float strength = 150F;//光照强度 100~150
int[] pixels = new int [width*height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for(int i = 1, length = height - 1; i < length; i++){
for(int k = 1, len = width - 1; k < len; k++){
pos = i * width + k;
pixColor = pixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = pixR;
newG = pixG;
newB = pixB;
//计算当前点到光照中心的距离,平面坐标系中求两点之间的距离
int distance = (int) (Math.pow((centerY - i),2) + Math.pow(centerX - k, 2));
if(distance < radius * radius){
//按照距离大小计算增加的光照值
int result = (int) (strength * (1.0 - Math.sqrt(distance) / radius));
newR = pixR + result;
newG = pixG + result;
newB = pixB + result;
}
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[pos] = Color.argb(MAX_VALUE, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
图片叠加效果:就是把我们要改变的图片作为背景再改变前景的透明度,这样就可以做出很多种效果了,只要变化前景的图片就行了。代码如下:
// 图片的叠加效果
private Bitmap overlay(Bitmap bmp){
int width = bmp.getWidth;
int height = bmp.getHeight;
Bitmap bitmap = bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
//对边框图片进行缩放
Bitmap overlay = BitmapFactory.decodeResource(mContext.getResources(),R.drawable.rainbow_overlay);
int w = overlay.getWidth();
int h = overlay.getHeight();
float scaleX = width * 1F / w;
float scaleY = height * 1F / h;
Matrix matrix = new Matrix();
matrix.postScale(scaleX, scaleY);
Bitmap overlayCopy = Bitmap.createBitmap(overlay, 0, 0, w, h, matrix, true);
int pixColor = 0;
int layColor = 0;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixA = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int newA = 0;
int layR = 0;
int layG = 0;
int layB = 0;
int layA = 0;
final float alpha = 0.5F;
int[] srcPixels = new int [width*height];
int[] layPixels = new int [width*height];
final float strength = 150F;//光照强度 100~150
bmp.getPixels(srcPixels, 0, width, 0, 0, width, height);
overlayCopy.getPixels(layPixels, 0, width, 0, 0, width, height);
int pos = 0;
for(int i = 0; i < height; i++){
for(int k = 0; k < width; k++){
pos = i * width + k;
pixColor = srcPixels[pos];
layColor = layPixels[pos];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
pixA = Color.alpha(pixColor);
layR = Color.red(layColor);
layG = Color.green(layColor);
layB = Color.blue(layColor);
layA = Color.alpha(layColor);
newR = (int) (pixR * alpha + layR * (1 - alpha));
newG = (int) (pixG * alpha + layG * (1 - alpha));
newB = (int) (pixB * alpha + layB * (1 - alpha));
layA = ((int) (pixA * alpha + layA * (1 - alpha));
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
newA = Math.min(255, Math.max(0, newA));
srcPixels[pos] = Color.argb(newA, newR, newG, newB);
}
}
bitmap.setPixels(srcPixels, 0, width, 0, 0, width, height);
return bitmap;
}
光晕效果:
// 光晕效果
private Bitmap halo(Bitmap bmp, int x, int y, float r){
int[] gauss = new int[] {1, 2, 1, 2, 4, 2, 1, 2, 1};
int width = bmp.getWidth;
int height = bmp.getHeight;
Bitmap bitmap = bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int delta = 18;//值越小图片会越亮
int idx = 0;
int[] pixels = new int [width*height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
int pos = 0;
for(int i = 1, length = height - 1; i < length; i++){
for(int k = 1, len = width - 1; k < len; k++){
idx = 0;
int distance = (int) (Math.pow(k - x, 2) + Math.pow(1 - y, 2));
//不是中心区域的点做模糊处理
if(distance > r * r){
for(int m = -1; m < = 1; m++){
for(int n = -1; n < = 1; n++){
pixColor = pixels[(i + m) * width + k + n];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = newR + (int) (pixR * gauss[idx]);
newG = pixG + (int) (pixG * gauss[idx]);
newB = pixB + (int) (pixB * gauss[idx]);
idx++;
}
}
newR /= delta;
newG /= delta;
newB /= delta;
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[i * width + k] = Color.argb(255, newR, newG, newB);
newR = 0;
newG = 0;
newB = 0;
}
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
模糊效果:
// 模糊效果
private Bitmap blurImageAmeliorate(Bitmap bmp, int x, int y, float r){
int[] gauss = new int[] {1, 2, 1, 2, 4, 2, 1, 2, 1};
int width = bmp.getWidth;
int height = bmp.getHeight;
Bitmap bitmap = bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int delta = 16;//值越小图片会越亮
int idx = 0;
int[] pixels = new int [width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for(int i = 1, length = height - 1; i < length; i++){
for(int k = 1, len = width - 1; k < len; k++){
idx = 0;
for(int m = -1; m < = 1; m++){
for(int n = -1; n < = 1; n++){
pixColor = pixels[(i + m) * width + k + n];
pixR = Color.red(pixColor);
pixG = Color.green(pixColor);
pixB = Color.blue(pixColor);
newR = newR + (int) (pixR * gauss[idx]);
newG = pixG + (int) (pixG * gauss[idx]);
newB = pixB + (int) (pixB * gauss[idx]);
idx++;
}
}
newR /= delta;
newG /= delta;
newB /= delta;
newR = Math.min(255, Math.max(0, newR));
newG = Math.min(255, Math.max(0, newG));
newB = Math.min(255, Math.max(0, newB));
pixels[i * width + k] = Color.argb(255, newR, newG, newB);
newR = 0;
newG = 0;
newB = 0;
}
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
看代码就会发现,光晕效果和模糊效果都是用了高斯数组,光晕只是局部的模糊效果。
黑色条纹效果:
//黑色条纹效果
public Bitmap stria(Bitmap bmp){
int width = bmp.getWidth();
int height = bmp.getHeight();
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);//创建一个相同大小的图片
//保存像素点的RGB值
int newR = 0;
int newG = 0;
int newB = 0;
int[] pixels = new int[width * height];//保存图片的像素点信息
bmp.getPixels(pixels, 0, width, 0, 0, width, height);//将整个图片保存到一维数组中,每width个长度为一行
final int delta = 40;//每40个像素的高度作为一个单位
final int blackHeight = 10;//黑色区域高度
final int BLACK = 0;
for (int i = 0; i < height; i++){
//对图片进行纵向处理
//每隔30个像素的高度就会产生一个高度为10个像素的黑色宽带
//每40个像素为一个单位,前面的10像素就会被处理成黑色
if (i % delta <=blackHeight){
for (int k = 0; k < width; k++ ){
//对当前像素点赋新的RGB值
newR = BLACK;
newG = BLACK;
newB = BLACK;
//Color.argb(),是将四个0~255的值组成一个像素点,也就是RGBA值,A是alpha,即透明度
pixels[i * width + k] = Color.argb(255, newR, newG,newB);//修改像素点
}
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);//向创建的相同大小的新图片绘像素点的值
return bitmap;
}
根据指定大小压缩图片
//根据指定大小压缩图片
public static Bitmap ShrinkBitmap(String file, int width, int height) {
if (file == null) {
return null;
}
BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
bmpFactoryOptions.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
int heightRatio = (int) Math.ceil(bmpFactoryOptions.outHeight
/ (float) height);
int widthRatio = (int) Math.ceil(bmpFactoryOptions.outWidth
/ (float) width);
if (heightRatio > 1 || widthRatio > 1) {
if (heightRatio > widthRatio) {
bmpFactoryOptions.inSampleSize = heightRatio;
} else {
bmpFactoryOptions.inSampleSize = widthRatio;
}
}
bmpFactoryOptions.inJustDecodeBounds = false;
bitmap = BitmapFactory.decodeFile(file, bmpFactoryOptions);
// bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
// bmpFactoryOptions);
return bitmap;
}
图片的旋转:
//旋转图片
public static Bitmap getRotateImage(Bitmap bitmap, int angle) {
if (angle <= 0 || bitmap == null) {
return bitmap;
}
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int newWidth = width;
int newHeight = height;
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newHeight) / height;
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
matrix.setRotate(angle, width / 2, height / 2);
Bitmap resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height,
matrix, true);
return resizeBitmap;
}
图片的反转:
//图片的反转
public static Bitmap reverseBitmap(Bitmap bmp, int flag){
float[] floats = null;
switch (){
case 0://水平反转
floats = new float[]{-1f, 0f, 0f,0f, 1f, 0f, 0f, 0f, 1f};
break;
case 1://垂直反转
floats = new float[]{1f, 0f, 0f, 0f, -1f, 0f, 0f, 0f, 1f};
break;
}
if(floats != null){
Matrix matrix = new Matrix();
matrix.setValues(floats);
return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
}
return bmp;
}