Android 怎么把一張圖片變?yōu)楹诎祝?br>
Android 怎么實(shí)現(xiàn)抖音上很火的黑金效果?
這篇文章給大家分享 RenderScript 怎么使用。
一、什么是 RenderScript ?
RenderScript 是 Android 自帶一個(gè)高效的計(jì)算框架,能夠自動(dòng)利用 CPU、GPU、DSP 來(lái)做并行計(jì)算,能在處理圖片、數(shù)學(xué)模型計(jì)算等場(chǎng)景提供高效的計(jì)算能力。
語(yǔ)法類似 C/C++, 但它是在運(yùn)行時(shí)編譯,是跨平臺(tái)的。性能比 Java 好,比 Native 略差。
二、如何使用 RenderScript ?
使用時(shí)分兩個(gè)步驟:
(1) 編寫(xiě) .rs 腳本文件;
(2) 使用編寫(xiě)的文件;
(1) 編寫(xiě) .rs 文件
這里我們用一個(gè)很簡(jiǎn)單的 將圖片置灰 為例實(shí)現(xiàn) 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 函數(shù):
root 函數(shù)是這個(gè)腳本的入口函數(shù),對(duì)于圖片來(lái)說(shuō),root函數(shù)負(fù)責(zé)對(duì)每一個(gè)像素做處理。
參數(shù) in 是輸入像素點(diǎn)的指針; out 是輸出像素點(diǎn)的指針。
init 函數(shù):
init 函數(shù)是可選的,用于做初始化的工作。
(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) {
// 創(chuàng)建輸出 bitamp
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Bitmap outBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
// 創(chuàng)建 RenderScript 對(duì)象
RenderScript rs = RenderScript.create(context);
// 創(chuàng)建輸入、輸出 Allocation
Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
// 創(chuàng)建我們?cè)谏厦娑x的 script
ScriptC_Gray script = new ScriptC_Gray(rs);
// 對(duì)每一個(gè)像素執(zhí)行 root 方法
script.forEach_root(allIn, allOut);
// 將執(zhí)行結(jié)果復(fù)制到輸出 bitmap 上
allOut.copyTo(outBitmap);
// 釋放資源
rs.destroy();
return outBitmap;
}
原圖和效果:


三、多個(gè) kernal 函數(shù)
除了 root 函數(shù),我們還可以在 .rs 中定義其他的 kernal 函數(shù),例如:
/**
* 黑金色轉(zhuǎn)換
*/
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;
}
其中函數(shù)返回值必須是 uchar4, 并且用 __attribute__((kernel)) 標(biāo)記該函數(shù)是個(gè) kernal 函數(shù)。
在 Java 代碼中這樣調(diào)用就可以了:
script.forEach_blackGold(allIn, allOut);
效果:

還可以在 .rs 文件中定義自己的結(jié)構(gòu)體,這里就不舉例啦。