【问题标题】:Build java application that uses opencv portable构建使用 opencv 可移植的 java 应用程序
【发布时间】:2019-10-02 07:59:47
【问题描述】:

我想创建 opencv 嵌入到包中的可执行 .jar 文件。我的意思是我可以在另一台计算机上运行它。拜托,有人帮助我吗???

我在文件SimpleSample.java中有此代码:

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import org.opencv.core.Scalar;

class SimpleSample {

  static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); }

  public static void main(String[] args) {
    System.out.println("Welcome to OpenCV " + Core.VERSION);
    Mat m = new Mat(5, 10, CvType.CV_8UC1, new Scalar(0));
    System.out.println("OpenCV Mat: " + m);
    Mat mr1 = m.row(1);
    mr1.setTo(new Scalar(1));
    Mat mc5 = m.col(5);
    mc5.setTo(new Scalar(5));
    System.out.println("OpenCV Mat data:\n" + m.dump());
  }
}

我尝试在用 Ant 构建后运行它,build.xml

<project name="SimpleSample" basedir="." default="rebuild-run">
    <property name="src.dir"     value="src"/>
    <property name="lib.dir"     value="${ocvJarDir}"/>
    <path id="classpath"><fileset dir="${lib.dir}" includes="**/*.jar"/></path>
    <property name="build.dir"   value="build"/>
    <property name="classes.dir" value="${build.dir}/classes"/>
    <property name="jar.dir"     value="${build.dir}/jar"/>
    <property name="main-class"  value="${ant.project.name}"/>
    <target name="clean"><delete dir="${build.dir}"/></target>
    <target name="compile">
        <mkdir dir="${classes.dir}"/>
        <javac includeantruntime="false" srcdir="${src.dir}" destdir="${classes.dir}" classpathref="classpath"/>
    </target>
    <target name="jar" depends="compile">
        <mkdir dir="${jar.dir}"/>
        <jar destfile="${jar.dir}/${ant.project.name}.jar" basedir="${classes.dir}">
            <manifest>
                <attribute name="Main-Class" value="${main-class}"/>
            </manifest>
        </jar>
    </target>
    <target name="run" depends="jar">
        <java fork="true" classname="${main-class}">
            <sysproperty key="java.library.path" path="${ocvLibDir}"/>
            <classpath>
                <path refid="classpath"/>
                <path location="${jar.dir}/${ant.project.name}.jar"/>
            </classpath>
        </java>
    </target>
    <target name="rebuild" depends="clean,jar"/>
    <target name="rebuild-run" depends="clean,run"/>
</project>

我遇到了这个异常:

线程“main”中的异常 java.lang.NoClassDefFoundError: org/opencv/core/Core at SimpleSample.(Unknown Source) Caused 由:java.lang.ClassNotFoundException:org.opencv.core.Core 在 java.net.URLClassLoader.findClass(URLClassLoader.java:381) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:424) 在 sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) 在 java.lang.ClassLoader.loadClass(ClassLoader.java:357) ... 1 更多

然后我尝试了eclipse,得到了这个:

线程“主”java.lang.UnsatisfiedLinkError 中的异常:否 java.library.path 中的 opencv_java300 位于 java.lang.ClassLoader.loadLibrary(ClassLoader.java:1864) 在 java.lang.Runtime.loadLibrary0(Runtime.java:870) 在 java.lang.System.loadLibrary(System.java:1122) 在 test.Test.(Test.java:10) 在 java.lang.Class.forName0(Native 方法)在 java.lang.Class.forName(Class.java:348) 在 org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:56)

我必须做什么才能生成可以正常工作的 jar 文件???谢谢!!

Obs:我已将 opencv 构建为静态库:

cmake -DBUILD_SHARED_LIBS=OFF ..

【问题讨论】:

    标签: java eclipse opencv executable-jar


    【解决方案1】:

    您需要将静态库与 jar 文件打包,将该静态库加载到临时文件中,然后从该路径加载您的静态库。

    在名为 opencv 的资源中创建一个文件夹,并将 .dll.dylib 文件放在相应的文件夹中。

    public class LoadLibrary {
    public static void loadOpenCV() {
        try {
            InputStream inputStream = null;
            File fileOut = null;
            String osName = System.getProperty("os.name");
            System.out.println(osName);
    
            if (osName.startsWith("Windows")) {
                int bitness = Integer.parseInt(System.getProperty("sun.arch.data.model"));
                if (bitness == 32) {
                    inputStream = LoadLibrary.class.getResourceAsStream("/opencv/windows/x86/opencv_java300.dll");
                    fileOut = File.createTempFile("lib", ".dll");
                } else if (bitness == 64) {
                    inputStream = LoadLibrary.class.getResourceAsStream("/opencv/windows/x64/opencv_java300.dll");
                    fileOut = File.createTempFile("lib", ".dll");
                } else {
                    inputStream = LoadLibrary.class.getResourceAsStream("/opencv/windows/x86/opencv_java300.dll");
                    fileOut = File.createTempFile("lib", ".dll");
                }
            } else if (osName.equals("Mac OS X")) {
                inputStream = LoadLibrary.class.getResourceAsStream("/opencv/mac/libopencv_java300.dylib");
                fileOut = File.createTempFile("lib", ".dylib");
            }
    
            if (fileOut != null) {
                OutputStream outputStream = new FileOutputStream(fileOut);
                byte[] buffer = new byte[1024];
                int length;
    
                while ((length = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, length);
                }
    
                inputStream.close();
                outputStream.close();
                System.load(fileOut.toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    }

    在 Main 中或调用 OpenCV 函数之前将 Static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } 更改为 LoadLibrary.loadOpenCV();

    并尝试从 Eclipse 中导出您的 jar 文件。它会工作得很好。

    【讨论】:

    • 我该怎么做??谢谢
    • 谢谢,但是我在linux下工作,没有dll,有.a和.so文件
    • 你能说说.so和.a文件的名字吗?
    • imgur.com/bMPZK7M 我所有的 .a 和 .so 文件,我确实把这些文件放在了我项目的 src 中,这些文件在 /src/opencv
    • 您将需要的文件将被命名为“libopencv_java300.so”,在资源的opencv目录中创建子文件夹并将其放入。在loadLibrary()函数中,检查linux并加载libopencv_java300.so文件。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-29
    • 2012-06-12
    相关资源
    最近更新 更多