【问题标题】:OnClickListener is not showing output of my functionOnClickListener 没有显示我的函数的输出
【发布时间】:2014-08-03 17:49:37
【问题描述】:

我做了2个功能,一个功能是给图像亮度,第二个功能是将图像转换为灰度,下面是我的jni代码(我使用android和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;
}

像上面那样在一个 cpp 文件中调用它两次/三次或多次 jni 方法是 Okay 吗?正如我想要的那样,如果我点击一个按钮,它应该执行亮度功能,当我点击第二个按钮时,它应该执行灰度,所以我是否要在这个场景中使用上面的cpp?

下面是我的java代码:

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

上面的代码工作正常并显示 eqhist 方法的输出

但是通过按钮点击调用函数(我在上面的代码中调整了下面的代码并且没有错误但它没有显示输出):

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

            }
        });

错误:

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)

编辑:

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>

【问题讨论】:

  • 您可以拥有多个函数,只要它们具有唯一的 jni 兼容名称。
  • @ChrisStratton 但是当我通过按钮调用jni 函数时,单击按钮后它不起作用,它强制关闭应用程序
  • 显示来自 logcat 的堆栈跟踪
  • 你在 UI 线程上做太多工作来阻止它。
  • 你的.cpp文件没有问题,activity和manifest.xml没有问题,java有问题,你的logcat呢?

标签: java android eclipse android-ndk java-native-interface


【解决方案1】:

正如我在评论中所说,您在 java 文件中几乎没有错误,您的其他文件还可以,您没有将结果放在按钮单击上,因此按钮没有可显示的内容(无图像视图),您的输出位图在按钮之外单击,您的位图在按钮单击时没有任何内容可显示,将这些行放在按钮单击中

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

当我在 android 上测试时,下面的代码对我有用,但它有点慢:

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


    }
    });

【讨论】:

    【解决方案2】:

    你不需要做两次。一个电话就能搞定。

    extern "C" {
    
    JNIEXPORT jint JNICALL Java_org_opencv_samples_NativeActivity_CvNativeActivity_grayimg(JNIEnv* env, jobject,jint width, jint height, jintArray in, jintArray out)
       {
           // process
       }
    
    JNIEXPORT jint JNICALL Java_org_opencv_samples_NativeActivity_CvNativeActivity_eqhist(JNIEnv* env, jobject,jint width, jint height, jintArray in, jintArray out)
       {
           // process
       }
    }
    int tobrightness(Mat mSrc, Mat& bgra)
    {
        // process
    }
    
    int toGray(Mat mSrc, Mat& bgra)
    {
        // process
    }
    

    现在在您的CvNativeActivity 中,您需要定义以下函数。

    public native int grayimg(int w, int h, int[] in, int[] out);
    public native int eqhist(int w, int h, int[] in, int[] out);
    

    您在将位图写入 .png 文件时似乎遇到了错误。使用OutputBitmapToFile 函数更新您的问题。

    另一种可能的解决方案是在新线程中调用此函数。

    public class ProcessTask extends AsyncTask<Void, Void, Boolean> {
    
        @Override
        protected Boolean doInBackground() {
            // this happens in a background thread
            eqhist(bmInImg.getHeight(), bmInImg.getWidth(), mPhotoIntArray, mCannyOutArray);
        }
    
        @Override
        protected void onPostExecute(Boolean result) {
            // save image, show image etc
            // This happens on the UI thread
        }
    }
    

    还有你的 onClick 调用,

    Button button= (Button) findViewById(R.id.NextButton);
            button.setOnClickListener(new OnClickListener() {
    
                @Override
                public void onClick(View v) {
                     ProcessTask task = new ProcessTask();
                     task.execute();
    
                }
            })
    

    【讨论】:

    • 我更新了我的问题,我想在按钮点击时使用这些功能
    • 几件事。您能否确保正在使用 Log 保存该文件(调用 OutoutBitmapToFile 函数)。此外,您还没有在清单中添加写入外部存储的用户权限。
    • 但是当我没有使用这个按钮点击时一切正常
    • 试试这个。通过 onClick 将功能添加到您的按钮。从现在开始删除 onClickListener。看看它是否有效。
    • 同样的结果,当我按下登录按钮时,它给了我以下日志输出:08-07 21:47:16.900: I/APP:(5548): Into OnClick of SettingDialog. View = android.widget.Button@420d2f10
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-25
    • 1970-01-01
    • 2021-05-25
    • 1970-01-01
    相关资源
    最近更新 更多