В прошлой статье был рассмотрен пример кода использования RenderScript с
помощью обычных Java - классов. Такой подход можно использовать в
обычной обработке изображений (размытие, матрица свертки). Чтоб
использовать все ресурсы RenderScript - не обойтись без написания кода
на языке С (стандарта С99). Такой код пишется в отдельный файл с
расширением .rs и содержится в специальной папке с названием "rs".
Пример программы будет выглядеть следующим образом:
Java файл.
Этот класс принимает в конструктор два параметра Context и Bitmap. Контекст нужен для инициализации RenderScript, а Bitmap - входящее изображение для обработки. Также нужно Создать копию по параметрам входящего изображения для результата (mBitmapsOut). Входящий и исходящий Bitmap должен быть сконфигурирован как .ARGB_8888 или .ARGB_4444 ( с альфа каналом ), на других форматах могут быть ошибки. Подключение файла .rs происходит через класс ScriptC_"название файла" ( в данном случае это ScriptC_draw - файл draw.rs). Запуск процесса идет через функцию mScript.forEach_"название функции"(...);
Стоит отметить сразу во избежании путаницы: Функция uchar4 __attribute__((kernel)) median(...) вызывается каждый раз для каждого пикселя отдельно, то есть функция обрабатывает только один пиксель за один раз, который передается в параметрах функции uchar4 in. Если необходимо задать цвет пикселя в зависимости от окружающих пикселей ( как на примере - медианный фильтр ) то необходимо в файл .rs передать целый обьект: mScript.set_"название переменной в файле .rs"(mInAllocation); В самом файле .rs создать переменную которая будет принимать байты пикселей всего изображения: rs_allocation inputAlloc; Функция uchar4 __attribute__((kernel)) median(...) также может принимать от системы координаты текущего пикселя uint32_t x, uint32_t y, от которого можно вычислять остальные. В конечном результате доступ к другим пикселям можно получить используя функцию uchar4 buff = rsGetElementAt_uchar4(inputAlloc, x + a , y + b); В RenderScript есть несколько типов переменных - векторов. Каждый вектор содержит данные о пикселе. Получать доступ к ним можно через оператор - точку : in.r = 255.
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.os.Handler;
- import android.support.v8.renderscript.Allocation;
- import android.support.v8.renderscript.RenderScript;
- import ivarious.xyz.Filters.ScriptC_draw;
- public class RenderScriptClass {
- Context context;
- Handler handler;
- private Bitmap mBitmapIn;
- private Bitmap mBitmapsOut;
- private RenderScript mRS;
- private Allocation mInAllocation;
- private Allocation mOutAllocations;
- private ScriptC_draw mScript;
- public MiandrRenderScript(Context arg, Bitmap arg_){
- mBitmapIn = arg_;
- context = arg;
- mBitmapsOut = Bitmap.createBitmap(mBitmapIn.getWidth(),mBitmapIn.getHeight(), Bitmap.Config.ARGB_8888);
- mRS = RenderScript.create(context);
- runScript();
- }
- public void runScript() {
- mInAllocation = Allocation.createFromBitmap(mRS,mBitmapIn);
- mOutAllocations = Allocation.createTyped(mRS, mInAllocation.getType());
- mScript = new ScriptC_draw(mRS);
- mScript.set_inputAlloc(mInAllocation);
- mScript.set_bWidht(mBitmapIn.getWidth());
- mScript.set_bHeight(mBitmapIn.getHeight());
- mScript.forEach_median(mInAllocation, mOutAllocations);
- mOutAllocations.copyTo(mBitmapsOut);
- }
- } }
Этот класс принимает в конструктор два параметра Context и Bitmap. Контекст нужен для инициализации RenderScript, а Bitmap - входящее изображение для обработки. Также нужно Создать копию по параметрам входящего изображения для результата (mBitmapsOut). Входящий и исходящий Bitmap должен быть сконфигурирован как .ARGB_8888 или .ARGB_4444 ( с альфа каналом ), на других форматах могут быть ошибки. Подключение файла .rs происходит через класс ScriptC_"название файла" ( в данном случае это ScriptC_draw - файл draw.rs). Запуск процесса идет через функцию mScript.forEach_"название функции"(...);
- rs_allocation inputAlloc;
- uchar4 __attribute__((kernel)) median(uchar4 in, uint32_t x, uint32_t y)
- {
- uchar4 arrpix[9];
- uchar4 buff;
- if((x<bWidht-1) && (y<bHeight-1)&&(x>=1) && (y>=1)){
- arrpix[0] = rsGetElementAt_uchar4(inputAlloc, x -1, y - 1);
- arrpix[1] = rsGetElementAt_uchar4(inputAlloc, x , y - 1);
- arrpix[2] = rsGetElementAt_uchar4(inputAlloc, x +1, y - 1);
- arrpix[3] = rsGetElementAt_uchar4(inputAlloc, x -1, y );
- arrpix[4] = rsGetElementAt_uchar4(inputAlloc, x , y );
- arrpix[5] = rsGetElementAt_uchar4(inputAlloc, x +1, y );
- arrpix[6] = rsGetElementAt_uchar4(inputAlloc, x -1, y+1);
- arrpix[7] = rsGetElementAt_uchar4(inputAlloc, x , y+1);
- arrpix[8] = rsGetElementAt_uchar4(inputAlloc, x +1, y+1);
- for(int i=0; i<=4; i++)
- for(int i=0; i<=8; i++){
- if(arrpix[i].r>arrpix[i+1].r){
- buff.r = arrpix[i].r; arrpix[i].r = arrpix[i+1].r;
- arrpix[i+1].r = buff.r;}
- if(arrpix[i].g>arrpix[i+1].g){
- buff.g = arrpix[i].g; arrpix[i].g = arrpix[i+1].g;
- arrpix[i+1].g = buff.g;}
- if(arrpix[i].b>arrpix[i+1].b){
- buff.b = arrpix[i].b; arrpix[i].b = arrpix[i+1].b;
- arrpix[i+1].b = buff.b;}
- }
- return arrpix[4];
- }
- else return in;
- } else return in;
Стоит отметить сразу во избежании путаницы: Функция uchar4 __attribute__((kernel)) median(...) вызывается каждый раз для каждого пикселя отдельно, то есть функция обрабатывает только один пиксель за один раз, который передается в параметрах функции uchar4 in. Если необходимо задать цвет пикселя в зависимости от окружающих пикселей ( как на примере - медианный фильтр ) то необходимо в файл .rs передать целый обьект: mScript.set_"название переменной в файле .rs"(mInAllocation); В самом файле .rs создать переменную которая будет принимать байты пикселей всего изображения: rs_allocation inputAlloc; Функция uchar4 __attribute__((kernel)) median(...) также может принимать от системы координаты текущего пикселя uint32_t x, uint32_t y, от которого можно вычислять остальные. В конечном результате доступ к другим пикселям можно получить используя функцию uchar4 buff = rsGetElementAt_uchar4(inputAlloc, x + a , y + b); В RenderScript есть несколько типов переменных - векторов. Каждый вектор содержит данные о пикселе. Получать доступ к ним можно через оператор - точку : in.r = 255.
Комментариев нет:
Отправить комментарий