Android 怎么把一张图片变为黑白?
Android 怎么实现抖音上很火的黑金效果?
这篇文章给大家分享 RenderScript 怎么使用。
一、什么是 RenderScript ?
RenderScript 是 Android 自带一个高效的计算框架,能够自动利用 CPU、GPU、DSP 来做并行计算,能在处理图片、数学模型计算等场景提供高效的计算能力。
语法类似 C/C++, 但它是在运行时编译,是跨平台的。性能比 Java 好,比 Native 略差。
二、如何使用 RenderScript ?
使用时分两个步骤:
(1) 编写 .rs 脚本文件;
(2) 使用编写的文件;
(1) 编写 .rs 文件
这里我们用一个很简单的 将图片置灰 为例实现 Gray.rs 文件;
#pragma version(1)
#pragma rs java_package_name(me.moolv.demo.rs)
void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) {
// a 是透明度,这里不修改透明度。
out->a = in->a;
// 快,但并不是真正意义的去色
out->r = out->g = out->b = (in->r + in->g + in->b) / 3;
// 慢,但是是真正的去色
// out->r = out->g = out->b = (in->r * 299 + in->g * 587 + in->b * 114 + 500) / 1000;
}
void init() {
}
第1行声明 RenderScript 的版本;
第2行 java_package_name 生命该脚本所在的Java包的包名;
root 函数:
root 函数是这个脚本的入口函数,对于图片来说,root函数负责对每一个像素做处理。
参数 in
是输入像素点的指针; out
是输出像素点的指针。
init 函数:
init 函数是可选的,用于做初始化的工作。
(2) 在 Java 代码中使用
在 Java 代码中 import:
import me.moolv.demo.rs.ScriptC_Gray;
这里的类名是 ScriptC_
加上 .rs 的文件名。包名就是在 rs 文件生声明的包名。
下面是具体使用:
/**
* 将 bitmap 去色后返回一张新的 Bitmap。
*/
public static Bitmap gray(@NonNull Context context, @NonNull Bitmap bitmap) {
// 创建输出 bitamp
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap outBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
// 创建 RenderScript 对象
RenderScript rs = RenderScript.create(context);
// 创建输入、输出 Allocation
Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
// 创建我们在上面定义的 script
ScriptC_Gray script = new ScriptC_Gray(rs);
// 对每一个像素执行 root 方法
script.forEach_root(allIn, allOut);
// 将执行结果复制到输出 bitmap 上
allOut.copyTo(outBitmap);
// 释放资源
rs.destroy();
return outBitmap;
}
原图和效果:
原图 去色三、多个 kernal 函数
除了 root 函数,我们还可以在 .rs 中定义其他的 kernal 函数,例如:
/**
* 黑金色转换
*/
uchar4 __attribute__((kernel)) blackGold(uchar4 in, uint32_t x, uint32_t y) {
uchar4 out = in;
if ((in.r < in.b) && (in.g < in.b)) {
out.r = out.g = out.b = (in.r*299 + in.g*587 + in.b*114 + 500) / 1000;
}
return out;
}
其中函数返回值必须是 uchar4
, 并且用 __attribute__((kernel))
标记该函数是个 kernal 函数。
在 Java 代码中这样调用就可以了:
script.forEach_blackGold(allIn, allOut);
效果:
黑金效果还可以在 .rs 文件中定义自己的结构体,这里就不举例啦。
网友评论