Я новичок в Android Renderscript. Мне нужно написать умножение свертки в RenderScript, так как окончательное приложение будет работать на Android. Поток данных будет изображением. В частности, я не могу написать основную логику, используя функциональность forEach, хотя я могу сделать это на Java, но слишком медленно! Пожалуйста помоги! Стив
Как написать умножение свертки в Android Renderscript?
Ответы (1)
Во время вызова rsForEach (или другой функции Renderscript) вы можете получить доступ к соседним пикселям исходного изображения (или любого другого типа данных, которые вы используете), привязав выделение исходного изображения к указателю в Renderscript, где к нему затем можно получить доступ как массив. Вот пример, основанный на примере HelloCompute:
#pragma version(1)
#pragma rs java_package_name(com.android.example.hellocompute)
rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;
static int mImageWidth;
const uchar4 *gPixels;
const float4 kWhite = {
1.0f, 1.0f, 1.0f, 1.0f
};
const float4 kBlack = {
0.0f, 0.0f, 0.0f, 1.0f
};
void init() {
}
static const int kBlurWidth = 20;
static const float kMultiplier = 1.0f / (float)(kBlurWidth * 2 + 1);
void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
float4 original = rsUnpackColor8888(*v_in);
float4 colour = original * kMultiplier;
int y_component = mImageWidth * y;
for ( int i = -kBlurWidth; i < 0; i++) {
float4 temp_colour;
if ( (int)x + i >= 0) {
temp_colour = rsUnpackColor8888(gPixels[x+i + y_component]);
}
else {
temp_colour = kWhite;
}
colour += temp_colour * kMultiplier;
}
for ( int i = 1; i <= kBlurWidth; i++) {
float4 temp_colour;
if ( x + i < mImageWidth) {
temp_colour = rsUnpackColor8888(gPixels[x+i + y_component]);
}
else {
temp_colour = kWhite;
}
colour += temp_colour * kMultiplier;
}
colour.a = 1.0f;
*v_out = rsPackColorTo8888(colour);
}
void filter() {
mImageWidth = rsAllocationGetDimX(gIn);
rsDebug("Image size is ", rsAllocationGetDimX(gIn), rsAllocationGetDimY(gOut));
rsForEach(gScript, gIn, gOut, NULL);
}
Вызывается из следующего Java. Обратите внимание на вызов mScript.bind_gPixels(mInAllocation), который связывает исходные данные изображения с указателем gPixel в Renderscript и, следовательно, делает данные изображения доступными в виде массива.
mRS = RenderScript.create(this);
mInAllocation = Allocation.createFromBitmap(mRS, mBitmapIn,
Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
mOutAllocation = Allocation.createTyped(mRS, mInAllocation.getType());
mScript = new ScriptC_blur(mRS, getResources(), R.raw.blur);
mScript.bind_gPixels(mInAllocation);
mScript.set_gIn(mInAllocation);
mScript.set_gOut(mOutAllocation);
mScript.set_gScript(mScript);
mScript.invoke_filter();
mOutAllocation.copyTo(mBitmapOut);
person
Massycat
schedule
21.04.2012
привет, спасибо за ваш код, и он работает хорошо; единственная проблема заключается в том, что root() выполняется для каждого пикселя в растровом изображении, верно? Могу ли я в любом случае запустить root() для каждой строки/столбца растрового изображения, чтобы я мог воспользоваться преимуществами этого быстрого алгоритма размытия?
- person xandy; 13.05.2012
Вызов rsForEach (выполняющий root()) будет выполняться для каждого элемента Allocation, который вы передаете. У вас должна быть возможность ограничить диапазон, в котором работает вызов rsForEach, но мне трудно заставить это работать (см. здесь).
- person Massycat; 16.05.2012
Хотя это, вероятно, не то, что вы хотите в любом случае. Если вы хотите, чтобы root() вызывался для каждой строки изображения, создайте выделение, которое представляет собой что-то вроде индексов данных изображения строки, и вызовите для этого rsForEach. Аргумент вывода данных внутри root() не может быть использован для вывода данных изображения, поэтому вам придется передать выделение выходного изображения аналогично передаче входного изображения, т.е. создать указатель внутри RenderScript и привязать к нему. со стороны Явы.
- person Massycat; 16.05.2012
Мой полный ответ на ваш связанный вопрос закончен.
- person Massycat; 16.05.2012