国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaWeb開發利用JNI調用C++代碼生成的dll進行圖像二值化處理并保存

cheukyin / 3457人閱讀

使用JNI進行Java與C/C++語言混合編程----在Java中調用C/C++生成的DLL動態鏈接庫

JNI是Java Native Interface的英文縮寫,
中文翻譯為本地調用, 自從Java 1.1開始就成為了Java標準的一部分.
Java調用C/C++大概有這樣幾個步驟

編寫帶有native方法的Java類, 使用javac工具編譯Java類

使用javah來生成與native方法對應的頭文件

實現相應的頭文件, 并編譯為動態鏈接庫(windows下是.dll, linux下是.so)

首先創建一個java工程,測試一下能不能調用openCV代碼:

 public class hello {
            //很多教程會叫我們聲明成static,但是我用的時候報錯了,所以我還是    
            //不聲明成static了
            public native void sayHello(String path);
            public static void main(String[] args) {
            // TODO Auto-generated method stub
            hello h=new hello();
            //有時候會報錯說cannot load  xxx.dll
            //只需要將生成的xxx.dll放到這                
               //條語句輸出的路徑下即可
            System.out.println(System.getProperty("java.library.path"));
            //這里調用的是java本地庫,TestAgain不加.dll。
            //怎樣生成.dll后面會介紹
            System.loadLibrary("TestAgain");
            
            h.sayHello("D:/images/5.jpg");
    
}

}

由于我用的是myeclipse編寫和編譯的Java程序,

只需要配置一下就可以用myeclipse生成xxx.h文件,

在myclipse->run->External Tools->External Tools configurations

一般需要選中一個工程才能run,然后就可以生成xxx.h頭文件了
working Directory:${project_loc}
arguments:-v -classpath "${project_loc}/src" -d "${project_loc}/jni"
${java_type_name}

制作.h文件還有一個更簡單的辦法,那就是直接cmd到當前工程的src目錄下,然后javah xxx(包名).xxx(類名),然后就可以了,舉例假設包名為com.action,類名為upLoad,而且src目錄下
則應該是javah com.action.upLoad即可

這里我也有些地方沒搞懂,因為我自己做這個項目的時候,用過jdk 1.6 1.7 1.8,最后使用的jdk1.6+tomcat6.0開發的,但是當我在location 中寫入jdk1.6 的bin/javah.exe,編譯我的javaweb工程時出現如下錯誤:

     ??????????? com.servlet.HandleImg
         δ??? com.servlet.HandleImg ???????
javadoc: ???? - ??????? com.servlet.HandleImg??
[ Search Path: D:jdkjdkjrelib
esources.jar;D:jdkjdkjrelib
t.jar;D:jdkjdkjrelibsunrsasign.jar;D:jdkjdkjrelibjsse.jar;D:jdkjdkjrelibjce.jar;D:jdkjdkjrelibcharsets.jar;D:jdkjdkjrelibmodulesjdk.boot.jar;D:jdkjdkjreclassesD:MyEclipseProfessional2014workspaceHandleImage/src ]
Error: δ??????????????κ?????????? -help??

因此我用的是我jdk1.7中bin/javah.exe生成的xxx.h頭文件,實在不行就只能下載兩個jdk了,知識水平有限,望有人能解決這個問題。

不管怎么說,最終頭文件是生成了,xxx.h文件在當前工程jni文件夾下,如下圖:

打開后

然后就可以開始寫c++代碼了
file->new ->project 選擇visual C++ 和win32 Console Application然后ok

我的操作系統和myeclipse都是64位的,因此生成32位的dll,在myeclipse中調用,會出現錯誤,這里就需要配一下

然后就是配置opencv環境,我用的是opencv2.4.4,具體的配置過程,去百度opencv2.4.4配置教程,這次是在debug|x64下添加propertySheet了,

繼續添加兩個路徑:C:Program FilesJavajdk1.7.0_80include和C:Program FilesJavajdk1.7.0_80includewin32,目的是為了引入三個頭文件jni.h和jni_md.h還有jawt_md.h

再就是右鍵工程 ->open folder in file explore 將上面生成的xxx.h文件copy到該文件夾下:

然后HeaderFile里面也放一份

第二種引入改頭文件的方法是直接新建一個頭文件Test.h(名字可以隨意取),然后將myEclipse中生成的頭文件的內容全部復制到Test.h中,然后在引用的時候將#include "com_Test_hello.h"改為#include "Test.h"即可

然后在source Files中新建TestAgain.cpp,代碼如下,

#include "com_Test_hello.h"
#include   
#include   
#include   
#include  
#include 

using namespace std;  
using namespace cv;


JNIEXPORT void JNICALL Java_com_Test_hello_sayHello
    (JNIEnv *env, jobject obj,jstring string){
     const char* str = env->GetStringUTFChars(string, 0);
    char cap[128];
    strcpy(cap, str);
    env->ReleaseStringUTFChars(string, 0);
    int len=strlen(cap);
    Mat imag, result;
    imag = imread(str,0);   //將讀入的彩色圖像直接以灰度圖像讀入  
    //namedWindow("原圖", 1);  
  //  imshow("原圖", imag);  
    result = imag.clone();  
   //進行二值化處理,選擇30,200.0為閾值  
    threshold(imag, result, 30, 200.0, CV_THRESH_BINARY);  
    //namedWindow("二值化圖像");  
   // imshow("二值化圖像", result); 
    imwrite(str,result);
    printf("圖像二值化成功!");
}

然后就可以build->build solution
如何使用Debug生成的解決方案的話,上面的那些環境就應該是在Debug下屬性表里面添加,而且生成的dll也是在Debug文件夾目錄下。
要是想用Release生成的話,同上步驟即可。

構建成功后可以在這里找到

將.dll文件復制到之前Java代碼中System.out.println(System.getProperty("java.library.path"));這條語句輸出的路徑中任何一個文件夾下即可
最后回到myeclipse中運行Java程序,就可以了
完成了這個調用后,就只需要將這個嵌入到javaweb工程中即可

有些時候調用dll需要返回int數組,或者字符串,我再分享這兩個方法
返回一個int數組
生成的頭文件用javah生成.h頭文件

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class Test_floatArray */

#ifndef _Included_Test_floatArray
#define _Included_Test_floatArray
#ifdef __cplusplus
extern "C" {
#endif
    /*
    * Class:     Test_floatArray
    * Method:    haha
    * Signature: ()[I
    */
    JNIEXPORT jintArray JNICALL Java_Test_floatArray_haha
        (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif
#include "Test.h"
#include 
JNIEXPORT jintArray JNICALL Java_Test_floatArray_haha
(JNIEnv *env, jobject obj){
    //1.新建長度len數組
    jintArray jarr = env->NewIntArray(3);
    //2.獲取數組指針
    jint *arr = env->GetIntArrayElements(jarr, NULL);
    //3.賦值
    int i = 0;
    for (; i < 3; i++){
        arr[i] = i;
    }
    //4.釋放資源
    env->ReleaseIntArrayElements(jarr, arr, 0);
    //5.返回數組
    return jarr;
}

返回一個字符串型數組,首先需要用一個stojstring()函數,將c++的string類型轉換為const char 類型,再從const char 轉化為jstring類型,即可直接返回一個jstring類型

#include "test.h"
#include 
#include 
using namespace std;

jstring stoJstring(JNIEnv* env, const char* pat)
{
    jclass strClass = env->FindClass("Ljava/lang/String;");
    jmethodID ctorID = env->GetMethodID(strClass, "", "([BLjava/lang/String;)V");
    jbyteArray bytes = env->NewByteArray(strlen(pat));
    env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat);
    jstring encoding = env->NewStringUTF("utf-8");
    return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
}

JNIEXPORT jstring JNICALL Java_com_action_upLoadAction_shibie
(JNIEnv *env, jobject obj, jstring path1, jstring path2, jstring path3){
    const char* str1 = env->GetStringUTFChars(path1, 0);
    const char* str2 = env->GetStringUTFChars(path2, 0);
    const char* str3 = env->GetStringUTFChars(path3, 0);

    printf("%s
", str1);
    printf("%s
", str2);
    printf("%s
", str3);
    printf("你好
");

    string str = "好#";
    const char* chardata = str.c_str();
    
    jstring jstr = stoJstring(env, chardata);

    return jstr;
}

test.h文件內容如下:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include 
/* Header for class com_action_upLoadAction */

#ifndef _Included_com_action_upLoadAction
#define _Included_com_action_upLoadAction
#ifdef __cplusplus
extern "C" {
#endif
    /*
    * Class:     com_action_upLoadAction
    * Method:    Contrast
    * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
    */
    JNIEXPORT void JNICALL Java_com_action_upLoadAction_Contrast
        (JNIEnv , jobject , jstring , jstring, jstring);
    JNIEXPORT jstring JNICALL Java_com_action_upLoadAction_shibie
        (JNIEnv *, jobject, jstring, jstring, jstring);
    

#ifdef __cplusplus
}
#endif
#endif

關于java web,推薦去看我的另一篇文章:https://segmentfault.com/a/11...

然后關于有些方法需要返回某個參數如String,boolean等,可以參考這篇文章:
http://www.cnblogs.com/icejoy...

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70389.html

相關文章

  • windows下簡單驗證碼識別——完美驗證碼識別系統

    摘要:可惜收費的,今天要介紹的完美驗證碼識別系統是類似的免費產品。調用函數相當簡單的,對比復雜的參數,這個識別是相當的快捷。 此文已由作者徐迪授權網易云社區發布。 歡迎訪問網易云社區,了解更多網易技術產品運營經驗。 講到驗證碼識別,大家第一個可能想到tesseract。誠然,對于OCR而言,tesseract確實很強大,自帶的字模能識別絕大多數規整的中英文。但是驗證碼畢竟不是OCR。對于現在...

    shleyZ 評論0 收藏0
  • iOS利用OpenCV 實現文字行區域提取嘗試

    摘要:這是坐標百度,好像沒啥好研究的了,不過出于好奇還是想知道使用是如何做到把文字區域進行框選的,所以接下來我們就看看如何在上使用實現圖片中的文字框選。一些探索 最近下了幾個OCR的App(比如白描),發現可以選中圖片中的文字行逐行轉成文字,覺得很有意思(當然想用要花錢啦),想著自己研究一下實現原理,google之后,發現了兩個庫,一個是OpenCV,在機器視覺方面應用廣泛,圖像分析必備利器。另一...

    番茄西紅柿 評論0 收藏0

發表評論

0條評論

cheukyin

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<