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>
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);
}
});