利用JNI实现JAVA插件开发
2011-09-29 09:56
363 查看
本文主要工作在于利用JNI实现对已经完成的视频镜头提取C++程序的调用。
整个过程如下所示:
1)将视频特征提取算法建立相应的windows下的Dll和Linux下的So(这个两个文件大家都知是什么了吧)
2)利用jni调用这些dll。但是有一个问题,就是这里的所有库文件需要打到jar包中,因此需要将这些文件先解压到一个临时文件夹中,然后通过Syste.load加载这些库文件。
如何利用JNI调用C、C++可以看我另一篇文章:/article/9282691.html
下面贴上程序:
VideoUtil.java
LoadVideoLib.java 该类主要是从jar包中将那些库文件解压到本地临时目录中来。有以下几点要注意
就是我在jar包中的库文件夹下放置了info文件,该文件中包含了该目录下的文件名。那么解压的时候先读取该info利用这些文件名,然后把所有该文件夹下的库文件都解压出来。这是一种折中的方式,应该有更好的方式,直接可以读取jar文件夹下的文件名列表。
另,生成info文件的代码也放到这里,可以直接调用。
如有疑问请留言
整个过程如下所示:
1)将视频特征提取算法建立相应的windows下的Dll和Linux下的So(这个两个文件大家都知是什么了吧)
2)利用jni调用这些dll。但是有一个问题,就是这里的所有库文件需要打到jar包中,因此需要将这些文件先解压到一个临时文件夹中,然后通过Syste.load加载这些库文件。
如何利用JNI调用C、C++可以看我另一篇文章:/article/9282691.html
下面贴上程序:
VideoUtil.java
package udms.video; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; public class VideoUtil { public static String path = ""; static { try{ // copy the so file to native temp dir String path = LoadVideoLib.loadLib(); // according to different operating system to load the library String systemType=System.getProperty("os.name"); systemType = systemType.toLowerCase(); if(systemType.contains("win")){ // windows dynamic link library. (dll) System.load(path+"cv210.dll"); System.load(path+"cxcore210.dll"); System.load(path+"cxts210.dll"); System.load(path+"highgui210.dll"); System.load(path+"VideoUtily.dll"); } else{ // linux share object. (so) System.load(path+"libavutil.so.51"); System.load(path+"libswscale.so.2"); System.load(path+"libavcodec.so.53"); System.load(path+"libavformat.so.53"); System.load(path+"libtiff.so"); System.load(path+"libcxcore.so.2.1"); System.load(path+"libcv.so.2.1"); System.load(path+"libml.so.2.1"); System.load(path+"libhighgui.so.2.1"); System.load(path+"libcvaux.so.2.1"); System.load(path+"libcxts.so.2.1"); System.load(path+"libVideoUtily.so"); } }catch(UnsatisfiedLinkError e){ System.err.println("Cannot load VideoUtil.so\n"+e.toString()); } } /** * extract the abstract frame from the video return the frame director path * @param fileName * @param abFrameNum * @param timeDisFlag * @return */ private native static String getAbstractFrameFromVideo(String fileName,int abFrameNum,int timeDisFlag); /** * extract the abstract frame from the video * @param videoPath the video file path * @param abFrameNum the number of abstract frame * @param timeDisFlag time flag * @return */ public static List<String> extractAbstractFrameFromVideo(String videoPath,int abFrameNum,int timeDisFlag) { List<String> reFiles=new ArrayList<String>(abFrameNum+1); String allPaths=getAbstractFrameFromVideo(videoPath,abFrameNum,timeDisFlag); StringTokenizer toker=new StringTokenizer(allPaths,"|"); while(toker.hasMoreTokens()){ reFiles.add(toker.nextToken()); } return reFiles; } }
LoadVideoLib.java 该类主要是从jar包中将那些库文件解压到本地临时目录中来。有以下几点要注意
就是我在jar包中的库文件夹下放置了info文件,该文件中包含了该目录下的文件名。那么解压的时候先读取该info利用这些文件名,然后把所有该文件夹下的库文件都解压出来。这是一种折中的方式,应该有更好的方式,直接可以读取jar文件夹下的文件名列表。
另,生成info文件的代码也放到这里,可以直接调用。
package udms.video; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; public class LoadVideoLib { /** * write the file name list of the directory to an info file. * @param path directory path */ public static void readFileList(String path){ try{ BufferedWriter bw = new BufferedWriter(new FileWriter(new File(path+"/info"))); File dir = new File(path); if(dir.isDirectory()){ String[] list = dir.list(); for(int i= 0 ;i < list.length; i++) bw.append(list[i]+"\r\n"); } bw.close(); }catch(Exception e){ e.printStackTrace(); } } /** * read the info from jar file. the info contain the file name of dll or so according to the os system. * @param infoPath info path in the jar * @return the file name list of dll or so. */ public static List<String> readInfo(String infoPath){ List<String> list = new ArrayList<String>(); // get the info input stream InputStream in = LoadVideoLib.class.getResourceAsStream(infoPath); BufferedReader br = new BufferedReader(new InputStreamReader(in)); String str = null; try{ // read the list of library file name from info while((str = br.readLine())!=null) list.add(str); br.close(); }catch(Exception e){ e.printStackTrace(); }finally{ try{ if(br!=null) br.close(); }catch(Exception e){ e.printStackTrace(); } } return list; } /** * load the relate library according to the os system. * @return the directory path of library. */ public static String loadLib(){ // get the os system name String systemType=System.getProperty("os.name"); systemType = systemType.toLowerCase(); // here only support windows and linux if(systemType.contains("win")) systemType="win"; else systemType="linux"; // judge the bit of os system. String bit = System.getProperty("os.arch"); String osType = ""; // here only support X86 and X64 if(bit.contains("64")) osType = systemType+"64"; else osType = systemType+"32"; // read the lib name list from info List<String> list = readInfo(osType+"/info"); // the director path which contains the library. String jarLibDir = osType+"/"; // get directory path which store the extracted library store in the jar file String nativeLibDir = System.getProperty("java.io.tmpdir")+"/"+osType; // extract the library file to the native library directory InputStream in=null; BufferedInputStream bis = null; BufferedOutputStream bos = null; for(String libName : list){ // create a native directory to store the library File libDir = new File(nativeLibDir); if(!libDir.exists()) libDir.mkdir(); // create the extracted library file File extractedLibFile=new File(nativeLibDir+"/"+libName); if(!extractedLibFile.exists()){ try{ in=LoadVideoLib.class.getResourceAsStream(jarLibDir+libName); bis = new BufferedInputStream(in); bos = new BufferedOutputStream(new FileOutputStream(extractedLibFile)); byte[] data = new byte[bis.available()]; bis.read(data); bos.write(data); bis.close(); bos.close(); }catch(IOException ioe){ ioe.printStackTrace(); }finally{ try{ if(bis!=null) bis.close(); if(bos!=null) bos.close(); }catch(Exception e){ e.printStackTrace(); } } } } // return the directory path which contains the library. return nativeLibDir+"/"; } }
如有疑问请留言
相关文章推荐
- Java利用flexpaper插件实现文档在线预览
- 利用Unity来实现插件开发
- Android Studio Jni开发(二)实现Native调用java方法和Native调用Android API
- Java项目开发心得(一):利用Java技术实现查询手机号码归属地
- 【Javaweb】利用urlRewrite插件实现网站的伪静态与aspx,jsp,php三版齐发的邪门歪道
- Android开发之如何保证Service不被杀掉 这只是介绍少走弯路 必须用C/jni 实现守护进程 java是无法实现的
- 混合开发-利用Cordova插件实现HTML5 与 原生代码的连接
- 利用Axis2开发WebService(3)---用Java实现调用WebService的客户端程序
- Java开发中网页截图的示例,采用jquery.imageaeraselect-0.9.10这个插件实现,自己详细测试过,可以使用。
- Java URLClassLoader实现插件功能开发
- 利用Java Swing 实现游戏开发
- 利用Java实现串口全双工通讯-Java基础-Java-编程开发
- 利用java语言在eclipse下实现在新浪微博开发平台发微博
- 利用Java Swing 实现游戏开发
- 利用JNI实现java的串口通讯技术(基于C++的底层)
- 利用Unity来实现插件开发
- Android开发之如何保证Service不被杀掉 这只是介绍少走弯路 必须用C/jni 实现守护进程 java是无法实现的
- [Java]利用java.util.concurrent实现多线程的线程池开发
- 利用 Java Swing 实现游戏开发
- Android利用JNI实现java调用C或C++