Search code examples
javaandroideclipseandroid-ndkjava-native-interface

OnClickListener is not showing output of my function


I make the 2 function , one function is give brightness to the image and second function is converting image into grayscale , below is my jni code for it (I am using android with eclipse)

int toGray(Mat mSrc, Mat& bgra);
int tobrightness(Mat mSrc, Mat& bgra);

extern "C" {

JNIEXPORT jint JNICALL Java_org_opencv_samples_NativeActivity_CvNativeActivity_grayimg(JNIEnv* env, jobject,jint width, jint height, jintArray in, jintArray out)
   {
       jint* _in = env->GetIntArrayElements(in, 0);
       jint* _out = env->GetIntArrayElements(out, 0);

       Mat mSrc(height, width, CV_8UC4, (unsigned char*)_in);
       Mat bgra(height, width, CV_8UC4, (unsigned char*)_out);

       int conv;
       jint retVal;
       conv = toGray(mSrc ,bgra);
       retVal = (jint)conv;

       env->ReleaseIntArrayElements(in, _in, 0);
       env->ReleaseIntArrayElements(out, _out, 0);
       return retVal;

   }
}


JNIEXPORT jint JNICALL Java_org_opencv_samples_NativeActivity_CvNativeActivity_eqhist(JNIEnv* env, jobject,jint width, jint height, jintArray in, jintArray out)
   {
       jint* _in = env->GetIntArrayElements(in, 0);
       jint* _out = env->GetIntArrayElements(out, 0);

       Mat mSrc(height, width, CV_8UC4, (unsigned char*)_in);
       Mat bgra(height, width, CV_8UC4, (unsigned char*)_out);
       Mat bgr(height, width, CV_8UC3);
       int conv;
       jint retVal;
       conv = tobrightness(mSrc, bgra);
       retVal = (jint)conv;

       env->ReleaseIntArrayElements(in, _in, 0);
       env->ReleaseIntArrayElements(out, _out, 0);
       return retVal;

}
int tobrightness(Mat mSrc, Mat& bgra)
{
    vector<Mat> sChannels;
    split(mSrc, sChannels);

    for(int i=0; i<sChannels.size(); i++)
    {
        Mat channel = sChannels[i];
        equalizeHist(channel, channel);
    }
    merge(sChannels, bgra);
    return 1;
}

int toGray(Mat mSrc, Mat& bgra)
{
    Mat gray(mSrc.rows, mSrc.cols, CV_8UC1);
    cvtColor(mSrc , gray , CV_BGRA2GRAY);
    cvtColor(gray , bgra , CV_GRAY2BGRA);
    return 1;
}

Is it Okay to call it twice/thrice or many times jni method in one cpp file like above I did ? As I want that if I click on one button it should perform the function of brightness and when I click on the second button it should perform grayscale , so am I going right with above cpp for this scenerio ?

below is my java code :

public class CvNativeActivity extends Activity
{
    public native int eqhist(int width, int height, int [] mPhotoIntArray, int [] mCannyOutArray);
    public native int grayimg(int width, int height, int [] mPhotoIntArray, int [] mCannyOutArray);

    static 
    {
        System.loadLibrary("native_activity");
        Log.i("EqActivity", "native library loaded successfully");
    }
    /** Called when the activity is first created. */ 
    ImageView imageview_1;
    ImageView imageview_2;

    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         imageview_1=(ImageView) findViewById(R.id.imageView1);
         imageview_2=(ImageView) findViewById(R.id.imageView2);

        InputStream is;
        is = this.getResources().openRawResource(R.drawable.me);
        Bitmap bmInImg = BitmapFactory.decodeStream(is);

        int [] mPhotoIntArray;
        int [] mCannyOutArray;

        mPhotoIntArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];
        imageview_1.setImageBitmap(bmInImg);
        // Copy pixel data from the Bitmap into the 'intArray' array
        bmInImg.getPixels(mPhotoIntArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());

        //create the Brightness result buffer
        mCannyOutArray = new int[bmInImg.getWidth() * bmInImg.getHeight()];


        eqhist(bmInImg.getHeight(), bmInImg.getWidth(), mPhotoIntArray, mCannyOutArray);
        grayimg(bmInImg.getHeight(), bmInImg.getWidth(), mPhotoIntArray, mCannyOutArray);

        //
        // Convert the result to Bitmap
        //
        Bitmap bmOutImg = Bitmap.createBitmap(bmInImg.getWidth(), bmInImg.getHeight(), Config.ARGB_8888);  
        bmOutImg.setPixels(mCannyOutArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());


        imageview_2.setImageBitmap(bmOutImg);
        String extStorageDirectory = Environment.getExternalStorageDirectory().toString();
        String outFileName = extStorageDirectory + "/me.png";

        OutputBitmapToFile(bmOutImg, outFileName);   
    }
}
void OutputBitmapToFile(Bitmap InBm, String Filename)
    {
        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        InBm.compress(Bitmap.CompressFormat.PNG, 100, bytes);

        File f = new File(Filename);
        try
        {
            f.createNewFile();
            //write the bytes in file
            FileOutputStream fo = new FileOutputStream(f);
            fo.write(bytes.toByteArray());

        } 
        catch (Exception e) 
        {
            e.printStackTrace();
        }           
    }
}

Above code work fine and showing output for eqhist method

But Calling function through button click (I adjusted below code in above code and getting no error but its not showing output) :

Button button= (Button) findViewById(R.id.NextButton);
        button.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                eqhist(bmInImg.getHeight(), bmInImg.getWidth(), mPhotoIntArray, mCannyOutArray);

            }
        });

Error :

08-05 00:42:21.656: E/ActivityManager(360): writeStringToFile error: /sys/kernel/debug/tracing/tracing_enabled java.io.FileNotFoundException: /sys/kernel/debug/tracing/tracing_enabled: open failed: ENOENT (No such file or directory)
08-05 00:57:56.150: E/ActivityManager(360): ANR in org.opencv.samples.NativeActivity (org.opencv.samples.NativeActivity/.CvNativeActivity)
08-05 00:57:56.150: E/ActivityManager(360): Reason: keyDispatchingTimedOut
08-05 01:18:16.986: E/Trace(20443): error opening trace file: No such file or directory (2)

Edit :

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#000000"
     >

    <ImageView
        android:id="@+id/imageView1"
        android:contentDescription="@null"
        android:layout_width="200dp"
        android:layout_height="200dp"
         />

    <ImageView
        android:id="@+id/imageView2"
        android:contentDescription="@null"
        android:layout_width="250dp"
        android:layout_height="250dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true" />

 <Button
     android:id="@+id/NextButton"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_alignBottom="@+id/imageView1"
     android:layout_alignParentRight="true"
     android:layout_marginRight="21dp"
     android:text="@string/Next_Button" />

</RelativeLayout>

Solution

  • As i said in comment your doing very little error in java file , your other files are okay , you are not putting your result on button click so button have nothing to display (no imageview) , your output bitmap is outside the button click , your bitmap has nothing to display on button click , Put these lines inside the button click

    Bitmap bmOutImg = Bitmap.createBitmap(bmInImg.getWidth(), bmInImg.getHeight(), Config.ARGB_8888);  
    bmOutImg.setPixels(mCannyOutArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());   
    imageview_2.setImageBitmap(bmOutImg);
    

    below code works for me as I tested on android but its bit slow :

    Button button= (Button) findViewById(R.id.NextButton);
    button.setOnClickListener(new OnClickListener() {
    
        @Override
    public void onClick(View v)  {
            // TODO Auto-generated method stub
            Log.i("APP: ", "Into OnClick of SettingDialog. View = " + v);
            eqhist(bmInImg.getHeight(),bmInImg.getWidth(), mPhotoIntArray, mCannyOutArray); 
            Bitmap bmOutImg = Bitmap.createBitmap(bmInImg.getWidth(), bmInImg.getHeight(), Config.ARGB_8888);  
            bmOutImg.setPixels(mCannyOutArray, 0, bmInImg.getWidth(), 0, 0, bmInImg.getWidth(), bmInImg.getHeight());   
            imageview_2.setImageBitmap(bmOutImg);
    
    
        }
        });