图片特效用到的函数
本文讲述的图片特效处理包括:怀旧、光照、光晕、底片、浮雕、模糊、锐化、黑白、冰冻、素描,所有这些特效都是基于一定的算法,对图像每个点的RGB值进行计算,并汇总所有点的计算结果生成新图片。特效处理主要用到Bitmap类的三个方法:
createBitmap : 创建一张新图片。
getPixels : 从指定图片中获取所有点的像素数组。
setPixels : 对指定图片设置所有点的像素数组。
图片怀旧效果
现实生活中的老相片都是泛黄的,而黄色又是由绿色和红色混合而成,所以怀旧效果为了突出黄色,就得加大绿色和红色的比重,同时降低蓝色的比重。下面是怀旧效果的结果截图:
下面是怀旧效果的示例代码:
// 图片怀旧效果
public static Bitmap nostalgic(Bitmap bmp) {
/*
* 怀旧处理算法即设置新的RGB R=0.393r+0.769g+0.189b G=0.349r+0.686g+0.168b B=0.272r+0.534g+0.131b
*/
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 k = 0; k < width; k++) {
pixColor = pixels[width * i + k];
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 + k] = newColor;
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
图片光照效果
现实生活中的相片,越靠近光源的区域,就显得越明亮。对应到图片中,便是越靠近光源中心的像素,就显得越白,越远离光源中心,就越没那么白。下面是光照效果的结果截图:
下面是光照效果的示例代码:
// 图片光照效果
public static Bitmap sunshine(Bitmap bmp) {
/*
* 算法原理:图片上面的像素点按照给定圆心,按照圆半径的变化,像素点的RGB值分别加上相应的值作为当前点的RGB值
*/
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 centerX = width / 2;
int centerY = height / 2;
int radius = Math.min(centerX, centerY);
float strength = 150F;// 光照强度100-150
int[] pixels = new int[width * height];
bmp.getPixels(pixels, 0, width, 0, 0, width, height);
for (int i = 1; i < height - 1; i++) {
for (int k = 1; k < width - 1; k++) {
// 获取前一个像素颜色
pixColor = pixels[width * i + k];
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 = newG + 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[width * i + k] = Color.argb(255, newR, newG, newB);
}
}
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
图片光晕效果
光晕与光照则恰恰相反,光晕表现为光源附近的区域显示正常,而界线以外的区域则显示暗淡。根据显示区域的形状,还可分为圆形光晕和矩形光晕两种常见类型。下面是光晕效果(圆形光晕)的结果截图:
下面是光晕效果(圆形光晕)的示例代码:
// 图片光晕效果(圆形光晕)
public static Bitmap haloCircle(Bitmap bmp) {
// 高斯矩阵
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 x = width / 2;
int y = height / 2;
float r = Math.min(x, y) / 2;
int pixR = 0;
int pixG = 0;
int pixB = 0;
int pixColor = 0;
int newR = 0;
int newG = 0;
int newB = 0;
int delta = 24; // 值越小图片会越亮,越大则越暗
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 j = 1, len = width - 1; j < len; j++) {
idx = 0;
int distance = (int) (Math.pow(j - x, 2) + Math.pow(i - y, 2));
// 不是中心区域的点做模糊处理
if (distance > r * r) {
for (int m = -1; m <= 1; m++) {
for (int n = -1; n <= 1; n++) {
pix