Android开发笔记(九十七)图片的特效处理

图片特效用到的函数

本文讲述的图片特效处理包括:怀旧、光照、光晕、底片、浮雕、模糊、锐化、黑白、冰冻、素描,所有这些特效都是基于一定的算法,对图像每个点的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
  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值