android-gpuimage-plus icon indicating copy to clipboard operation
android-gpuimage-plus copied to clipboard

Pass two bitmaps into shaders.

Open soham24 opened this issue 5 years ago • 6 comments

Hello, I can see with the use of image handler I can get bitmap into OpenGL texture and apply a filter on it. But I want to perform some custom blend operation in the shader.

basically, I want to pass two bitmaps and get them in the shader as texture like this.

Bitmap dstImage = CGENativeLibrary.filterImage_MultipleEffects(**bmp1,bmp2**, ruleString, 1.0f);

any suggestions about the approach?

soham24 avatar Mar 28 '19 15:03 soham24

You should write your own filter in c++, please follow the manual in the README.md

wysaid avatar Mar 28 '19 17:03 wysaid

I have modified this method to take input bitmap

`JNIEXPORT jobject JNICALL Java_org_wysaid_nativePort_CGENativeLibrary_cgeFilterImage_1MultipleEffects (JNIEnv *env, jclass cls, jobject bmp,jobject bmp1, jstring config, jfloat intensity) { CGETexLoadArg texLoadArg; texLoadArg.env = env; texLoadArg.cls = cls;

AndroidBitmapInfo info;
int w, h, ret;
char* row;

CGE_LOG_CODE(clock_t tm = clock();)

if ((ret = AndroidBitmap_getInfo(env, bmp, &info)) < 0)
{
    CGE_LOG_ERROR("AndroidBitmap_getInfo() failed ! error=%d", ret);
    return nullptr;
}
CGE_LOG_INFO("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",
 info.width, info.height, info.stride, info.format, info.flags);
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
{
    CGE_LOG_ERROR("Bitmap format is not RGBA_8888 !");
    return nullptr;
}

// get the basic information of the image
w = info.width;
h = info.height;

jobject newBitmap;
jclass bitmapCls = env->GetObjectClass(bmp);

ret = AndroidBitmap_lockPixels(env, bmp, (void**) &row);
if (ret < 0)
{
    CGE_LOG_ERROR("AndroidBitmap_lockPixels() failed ! error=%d", ret);
    return nullptr;
}



AndroidBitmapInfo info1;
int w1, h1, ret1;
char* row1;

CGE_LOG_CODE(clock_t tm1 = clock();)

if ((ret1 = AndroidBitmap_getInfo(env, bmp1, &info1)) < 0)
{
    CGE_LOG_ERROR("AndroidBitmap_getInfo() failed ! error=%d", ret1);
    return nullptr;
}

CGE_LOG_INFO("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d", info1.width,
        info1.height, info1.stride, info1.format, info1.flags);
if (info1.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
{
    CGE_LOG_ERROR("Bitmap format is not RGBA_8888 !");
    return nullptr;
}

// get the basic information of the image
w1 = info1.width;
h1 = info1.height;

jobject newBitmap1;
jclass bitmapCls1 = env->GetObjectClass(bmp1);

ret1 = AndroidBitmap_lockPixels(env, bmp1, (void**) &row1);
if (ret1 < 0)
{
    CGE_LOG_ERROR("AndroidBitmap_lockPixels() failed ! error=%d", ret1);
    return nullptr;
}

CGESharedGLContext* glContext = CGESharedGLContext::create();
if(glContext == nullptr)
{
    CGE_LOG_ERROR("Create Context Failed!");
    return bmp;
}

glContext->makecurrent();

{
    CGEImageHandler handler;
    handler.initWithRawBufferData(row1, w1, h1, CGE_FORMAT_RGBA_INT8, false);
    AndroidBitmap_unlockPixels(env, bmp1);

    CGEMutipleEffectFilter* filter = new CGEMutipleEffectFilter;

    filter->setTextureLoadFunction(cgeGlobalTextureLoadFunc, &texLoadArg);

    const char* strConfig = env->GetStringUTFChars(config, 0);
    filter->initWithEffectString(strConfig);
    env->ReleaseStringUTFChars(config, strConfig);

    filter->setIntensity(intensity);

    handler.addImageFilter(filter);
    handler.processingFilters();

    jmethodID createBitmapFunction = env->GetStaticMethodID(bitmapCls, "createBitmap", "(IILandroid/graphics/Bitmap$Config;)Landroid/graphics/Bitmap;");
    jstring configName = env->NewStringUTF("ARGB_8888");
    jclass bitmapConfigClass = env->FindClass("android/graphics/Bitmap$Config");
    jmethodID valueOfBitmapConfigFunction = env->GetStaticMethodID(bitmapConfigClass, "valueOf", "(Ljava/lang/String;)Landroid/graphics/Bitmap$Config;");
    jobject bitmapConfig = env->CallStaticObjectMethod(bitmapConfigClass, valueOfBitmapConfigFunction, configName);
    env->DeleteLocalRef(configName);
    newBitmap = env->CallStaticObjectMethod(bitmapCls, createBitmapFunction, info.width, info.height, bitmapConfig);

    ret = AndroidBitmap_lockPixels(env, newBitmap, (void**) &row);
    if (ret < 0)
    {
        CGE_LOG_ERROR("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        // AndroidBitmap_unlockPixels(env, bmp);
        return nullptr;
    }

    handler.getOutputBufferData(row, CGE_FORMAT_RGBA_INT8);
    AndroidBitmap_unlockPixels(env, newBitmap);
}

CGE_LOG_INFO("unlocked pixels, function totalTime: %g s", (clock() - tm) / (float)CLOCKS_PER_SEC);

delete glContext;
return newBitmap;

}

` I have passed 2 bitmaps in cpp code, and both are loading. How to pass those 2 bitmaps to shader?

I see this method of handler handler.initWithRawBufferData(row1, w1, h1, CGE_FORMAT_RGBA_INT8, false);

should I make one more method in handler like initWithRawBufferData1? and pass secondbitmap?

If I do that, how I can get that in shader?
I know passing textures in opengl shaders, but this shader which has originImageTexture I am not able to figure out the way how you did it. and how to replicate it to add one more texture to shader.

or instead of adding initWithRawBufferData1? method to handler , I should add addTexture method to shader?

soham24 avatar Mar 29 '19 06:03 soham24

Can you explain why you want to pass two images to one shader ?

wysaid avatar Mar 30 '19 07:03 wysaid

Normally, we use one origin input image, and some resource images to do filter. As the resource is put in the right place, we can load them by calling loading function

wysaid avatar Mar 30 '19 07:03 wysaid

And if you're doing filter with two results, maybe you should build your own rendering pipeline to finish it without extra bitmap results.

wysaid avatar Mar 30 '19 07:03 wysaid

Actually, my friend/developer, who is image processing guy, has written some algorithm in opencv which takes some sequence of images and processes them. to make his algorithm faster, he developed it in opengl. now I want to port it in android.

soham24 avatar Mar 31 '19 18:03 soham24