美文网首页
Android 如何利用 RenderScript 将图片处理为

Android 如何利用 RenderScript 将图片处理为

作者: 郑海鹏 | 来源:发表于2020-04-04 18:35 被阅读0次

    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 文件中定义自己的结构体,这里就不举例啦。

    相关文章

      网友评论

          本文标题:Android 如何利用 RenderScript 将图片处理为

          本文链接:https://www.haomeiwen.com/subject/puzjphtx.html