当前位置:   article > 正文

SpringBoot整合百度人脸识别SDK离线版操作步骤,Windows发布打包SpringBoot百度人脸识别SDK项目,以及解决百度人脸识别SDK离线版遇到的问题

百度人脸识别sdk

前言

1、下载百度人脸识别SDK离线版。
2、开发工具:IntelliJ IDEA
百度人脸识别官网:https://cloud.baidu.com/doc/FACE/s/Ol0rre5u5
注意:最后面有基于SDK的简单人脸库实现,可添加修改人脸库,且可以分析比对分数

步骤

一、基本测试

1、解压下载的百度人脸识别SDK包(x64内带教程文档)。

在这里插入图片描述

2、IDEA中直接打开FaceOfflineSdk

3、然后引入当前项目下的opencv-jar目录下的jar包

  1. 引入点这里,idea右上角
    在这里插入图片描述

  2. 跟着操作即可,然后引入当前项目下的opencv-jar目录下的jar包
    在这里插入图片描述

  3. 一般引入后应用,在modules那边的dependencies就可以看到。

  4. 打开这个工具,然后将百度申请的16位激活码填充,点击激活后会生成license文件夹,然后复制这个文件夹替换对应的license文件。
    在这里插入图片描述

  5. 再到idea找到com.jni.face.Face.java然后执行main方法就可以开始测试了,这个类中的方法都有注释,根据需求调用就好了。

二、整合项目

创建一个项目直接FaceOfflineSdk目录下的几个文件夹复制到新项目中
在这里插入图片描述

在这里插入图片描述
同上面一样引入opencv-320.jar包即可

三、打包,及打包后遇到的问题

打包/后

  1. 打包后发布将项目下的所有dll文件放到 C:\windows\system32 或 C:\Program Files\Java\jre1.8.0_181\bin 目录下(这个目录下可以找 face_sdk.log 查看日志)。
  2. 打包后需要自己在代码上动态的将16位激活码替换license下的license.key文件,联网情况下自动激活的。
  3. 将license文件夹和models文件夹放到一个新的文件夹中,然后将这个新的文件夹路径替换下面代码中的那个模型路径。
	Face api = new Face();
    // model_path为模型文件夹路径,即models文件夹(里面存的是人脸识别的模型文件)
    String modelPath = ""; // D:\\FaceOfflineSdk\\
    int res = api.sdkInit(modelPath);
    if (res != 0) {
        System.out.printf("sdk init fail and error =%d\n", res);
        return;
    }
    
    // sdk销毁,释放内存防内存泄漏
    api.sdkDestroy();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

打包遇到的问题:

  1. 打包后Windows下一直报 -4 错误(一直找不到模型)。

    解决:需要使用双斜杠,单斜杠虽然通用但是Windows下无效。(找了一天问题差点气嘎了,后面问百度技术才解决的)
    在这里插入图片描述

  2. 打包war后报 java.lang.NoClassDefFoundError: org/opencv/imgcodecs/Imgcodecs 错误。

解决:操作pom.xml,打包后没有将opencv-320.jar生成到lib下,需要改成如下

<build>
    <finalName>face-analysis-service</finalName>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <includeSystemScope>true</includeSystemScope>
            </configuration>
        </plugin>
        <!-- 打包war防止上面引入的本地jar添加到 lib-provided 文件夹中而读取不了-->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <configuration>
                <webResources>
                    <resource>
                        <directory>${project.basedir}/opencv-jar</directory>
                        <targetPath>WEB-INF/lib/</targetPath>
                        <includes>
                            <include>**/*.jar</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>
    </plugins>
</build>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

以上即可!

其他博客参考:https://www.jianshu.com/p/f4e6de80e72a

基于百度SDK重写了人脸库用来分析比对

实现注意:
1、更改com.jni.struct.Feature对象,将这个对象加入实现序列化(因为要存到文件中)。
2、实现比较简单,利用Face.java下的几个方法实现如下逻辑
3、我这里使用了文件形式存储,也可写成数据库存储,根据需求分组查询就好;每个特征值是 512字节(0.5kb)比较小,所以存数据库也是可以的

准备一个ArrayList<Map<String, Feature>> featureList;

一、人脸校验是否是没有人脸,或者是否多人脸,如果是则返回错误;如果就一个人脸就正常进入下一步(方法:detect)。

二、校验featureList中是否存在这个人脸,如果没有则添加,有就修改。

三、将照片转成特征值(方法:faceFeature),然后添加/修改成本地文件,并添加/修改到featureList。

四、如果是删除人员照片则,删除featureList中特征值,再删除本地文件。

五、分析校验:将当前通行照片转成特征值,然后循环featureList拿出特征值比较(比较方法:compareFeature)并然后float的分数和map的key工号。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

com.jni.struct.Feature对象修改如下

在这里插入图片描述

新建一个类,这里定义FaceEntity.java

package com.common.entity;

import lombok.Data;

import java.io.Serializable;

/**
 * 人脸识别分数
 *
 * @author yyq
 */
@Data
public class FaceEntity implements Serializable {

    /**
     * ID
     */
    private String id;
    /**
     * 人脸识别分数
     */
    private float score;


}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

然后就是实现了,创建FaceUtil.java类

比较简单的实现,复制过去就可以用,需要注意 ImageUtil.NGINXPATH 等于 D://face_file//,把它改成自己的路径就可以了

package com.common.util;

import com.common.entity.FaceEntity;
import com.jni.face.Face;
import com.jni.face.TimeUtil;
import com.jni.struct.FaceBox;
import com.jni.struct.Feature;
import com.jni.struct.FeatureInfo;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * 人脸识别自定义分析库
 *
 * @author yyq
 * @date 2023-04-01
 */
public class FaceUtil {

    /**
     * 人脸库
     */
    public static ArrayList<Map<String, Feature>> list = new ArrayList<>();
    /**
     * 人脸特征值文件存储路径
     */
    public static String filePath = "/upload/face_datebase/";
    /**
     * 人脸库加载状态:true加载完毕
     */
    public static boolean load_state = false;


    /**
     * 检测到人脸,是否只有一张
     * 0没有人脸 1有多个人脸 2只有一个人脸
     *
     * @return
     */
    public static int detect(long matAddr, int type) {
        FaceBox[] infos = Face.detect(matAddr, type);// 检测人脸
        if (infos == null) {
            return 0;
        } else if (infos.length > 1) {
            return 1;
        } else if (infos.length == 1) {
            return 2;
        }
        return 0;
    }

    /**
     * 获取人脸特征值
     *
     * @param matAddr
     * @param type
     * @return
     */
    public static Feature getFeature(long matAddr, int type) {
        FeatureInfo[] fea1List = Face.faceFeature(matAddr, type);
        if (fea1List != null && fea1List.length > 0) {
            return fea1List[0].feature;
        }
        return null;
    }

    /**
     * 添加到人脸库
     *
     * @param id
     * @param feature
     * @return
     */
    public static boolean addUser(String id, Feature feature, boolean file) {
        try {
            Map<String, Feature> featureMap = new HashMap<>();
            featureMap.put(id, feature);
            FaceUtil.list.add(featureMap);
            if (file) {// 是否存储文件
                writeObject(ImageUtil.NGINXPATH + FaceUtil.filePath, id, feature);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 修改人脸库指定下标的人脸
     *
     * @param id
     * @param feature
     * @return
     */
    public static boolean updateUser(int index, String id, Feature feature) {
        try {
            // 修改人脸库list
            FaceUtil.list.get(index).put(id, feature);
            // 重新写入
            writeObject(ImageUtil.NGINXPATH + FaceUtil.filePath, id, feature);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 添加/修改
     *
     * @param id
     * @param feature
     * @return -1添加失败 -2修改失败 0 操作失败 1添加成功 2修改成功
     */
    public static int addOrUpdateUser(String id, Feature feature) {
        try {
            int index = exists(id);
            if (index != -1) {
                boolean b = updateUser(index, id, feature);
                return b ? 2 : -2;
            } else {
                boolean b = addUser(id, feature, true);
                return b ? 1 : -1;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 删除人脸库的人脸
     *
     * @param id
     * @return
     */
    public static boolean deleteUser(String id) {
        try {
            for (int i = 0; i < FaceUtil.list.size(); i++) {
                Map<String, Feature> featureMap = FaceUtil.list.get(i);
                if (getKey(featureMap, id)) {
                    FaceUtil.list.remove(i);
                    ImageUtil.deleteFile(ImageUtil.NGINXPATH + FaceUtil.filePath + id);
                    return true;
                }
            }
            return false;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 判断是否存在人脸库
     *
     * @param id
     * @return
     */
    public static int exists(String id) {
        try {
            for (int i = 0; i < FaceUtil.list.size(); i++) {
                Map<String, Feature> featureMap = FaceUtil.list.get(i);
                if (getKey(featureMap, id)) {
                    return i;
                }
            }
            return -1;
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    /**
     * 获取判断map中是否有这个key
     *
     * @param map
     * @param key
     * @return
     */
    public static boolean getKey(Map<String, Feature> map, String key) {
        for (Map.Entry<String, Feature> m : map.entrySet()) {
            if (m.getKey().equals(key)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 比较人脸
     *
     * @param path
     * @return
     */
    public static FaceEntity compareFace(String path) {
        try {
            // 如果库里没有特征值
            if (FaceUtil.list.size() <= 0) {
                return null;
            }
            Mat mat = Imgcodecs.imread(path);// 开始将路径图片转成特征值
            long matAddr = mat.getNativeObjAddr();
            int type = 0;// type 0: 表示rgb生活照特征值,1:表示rgb证件照特征值 2:表示nir近红外特征值
            FeatureInfo[] fea1List = Face.faceFeature(matAddr, type);
            if (fea1List == null || fea1List.length <= 0) {
                return null;
            }
            // 循环库
            FaceEntity faceEntity = new FaceEntity();
            float maxScore = 0; // 最大分数
            String maxId = null; // 最大分数的ID
            for (Map<String, Feature> featureMap : FaceUtil.list) {
                for (Map.Entry<String, Feature> m : featureMap.entrySet()) {
                    Feature feature = m.getValue();
                    for (FeatureInfo info : fea1List) {
                        float score = Face.compareFeature(feature, info.feature, type);// 比较特征值
                        if (score > maxScore) {
                            maxScore = score;
                            maxId = m.getKey();
                        }
                    }
                }
            }
            faceEntity.setId(maxId);
            faceEntity.setScore(maxScore);
            return faceEntity;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 初始化人脸库list
     */
    public static void initList() {
        try {
            String path = ImageUtil.NGINXPATH + FaceUtil.filePath;
            File file = new File(path);
            if (!file.exists()) {
                return;
            }
            File[] files = file.listFiles();
            for (File f : files) {
                String id = f.getName();
                Feature feature = (Feature) readObject(path + id);
                addUser(id, feature, false);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 写入文件
     *
     * @param path
     * @param obj
     * @throws IOException
     */
    public static void writeObject(String path, String fileName, Object obj) throws IOException {
        File file = new File(path);
        if (!file.exists()) {
            file.mkdirs();
        }
        File f = new File(path + fileName);
        if (f.exists()) {
            ImageUtil.deleteFile(path + fileName);
            f = new File(path + fileName);
        }
        FileOutputStream out = new FileOutputStream(f);
        ObjectOutputStream objwrite = new ObjectOutputStream(out);
        objwrite.writeObject(obj);
        objwrite.flush();
        objwrite.close();
    }

    /**
     * 读取文件
     *
     * @param path
     * @return
     * @throws IOException
     * @throws ClassNotFoundException
     */
    public static Object readObject(String path) throws IOException, ClassNotFoundException {
        FileInputStream in = new FileInputStream(path);
        ObjectInputStream objread = new ObjectInputStream(in);
        Object obj = objread.readObject();
        objread.close();
        return obj;
    }


    public static void main(String[] args) {
        //sdk初始化
        Face api = new Face();
        // model_path为模型文件夹路径,即models文件夹(里面存的是人脸识别的模型文件)
        // 传空为采用默认路径,若想定置化路径,请填写全局路径如:d:\\face (models模型文件夹目录放置后为d:\\face\\models)
        // 若模型文件夹采用定置化路径,则激活文件(license.ini, license.key)也可采用定制化路径放置到该目录如d:\\face\\license
        // 亦可在激活文件默认生成的路径
        String modelPath = ""; // F:\Development-Tool\IDEA-SVN\FaceOfflineSdk\models
        int res = api.sdkInit(modelPath);
        if (res != 0) {
            System.out.printf("sdk init fail and error =%d\n", res);
            return;
        }
        long begin = TimeUtil.getTimeStamp();


        /**
         *
         * 加载人脸库
         *
         */
        // 初始化人脸库
        initList();
        System.out.println("---------------------人脸库总数:" + list.size());


        /**
         *
         * 新增图片到人脸库
         *
         *
         */
        // 开始将路径图片转成特征值
        Mat mat = Imgcodecs.imread("images/1.jpg");
        long matAddr = mat.getNativeObjAddr();
        int type = 0;// type 0: 表示rgb生活照特征值,1:表示rgb证件照特征值 2:表示nir近红外特征值

        int detect = detect(matAddr, type);
        if (detect == 0) {
            System.out.println("---------------------没有检测到人脸");
        } else if (detect == 1) {
            System.out.println("---------------------检测到多张人脸");
        } else {
            System.out.println("---------------------检测到一张人脸");
            Feature feature = getFeature(matAddr, type);
            if (feature != null) {
                int i = addOrUpdateUser("101", feature);
                if (i == 0) {
                    System.out.println("---------------------【人脸注册异常】");
                } else if (i == -1) {
                    System.out.println("---------------------【人脸添加失败】");
                } else if (i == -2) {
                    System.out.println("---------------------【人脸修改失败】");
                } else if (i == 1) {
                    System.out.println("---------------------【人脸添加成功】");
                } else if (i == 2) {
                    System.out.println("---------------------【人脸修改成功】");
                }
            } else {
                System.out.println("---------------------获取人脸特征值失败");
            }
        }

        long end = TimeUtil.getTimeStamp();
        System.out.println("新增耗时 ----------- :" + (end - begin));


        begin = TimeUtil.getTimeStamp();
        // 图片路径人脸比对
        FaceEntity faceEntity = compareFace(ImageUtil.NGINXPATH + "1.jpg"); // ImageUtil.NGINXPATH 等于 D://face_file//
        if (faceEntity != null) {
            System.out.println("---------------------[人脸比对返回] id:" + faceEntity.getId() + "  分数:" + faceEntity.getScore());
        } else {
            System.out.println("---------------------[人脸比对-人脸库为空]");
        }
        end = TimeUtil.getTimeStamp();
        System.out.println("比对耗时 ----------- :" + (end - begin));

        // sdk销毁,释放内存防内存泄漏
        api.sdkDestroy();


    }


}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
  • 299
  • 300
  • 301
  • 302
  • 303
  • 304
  • 305
  • 306
  • 307
  • 308
  • 309
  • 310
  • 311
  • 312
  • 313
  • 314
  • 315
  • 316
  • 317
  • 318
  • 319
  • 320
  • 321
  • 322
  • 323
  • 324
  • 325
  • 326
  • 327
  • 328
  • 329
  • 330
  • 331
  • 332
  • 333
  • 334
  • 335
  • 336
  • 337
  • 338
  • 339
  • 340
  • 341
  • 342
  • 343
  • 344
  • 345
  • 346
  • 347
  • 348
  • 349
  • 350
  • 351
  • 352
  • 353
  • 354
  • 355
  • 356
  • 357
  • 358
  • 359
  • 360
  • 361
  • 362
  • 363
  • 364
  • 365
  • 366
  • 367
  • 368
  • 369
  • 370
  • 371
  • 372
  • 373
  • 374
  • 375
  • 376
  • 377
  • 378
  • 379
  • 380
  • 381
  • 382
  • 383
  • 384
  • 385
  • 386
  • 387
  • 388
  • 389
  • 390

执行人脸注册的时候服务突然关闭/停止问题解决

问题:通过接口注册人脸照片到人脸库的时候,突然服务就停止了!
解决:由于百度算法不支持主线程操作,所以我们写个子线程就好了。

如下
声明子线程处理

package com.common.thread;

import com.common.util.FaceUtil;
import org.opencv.core.Mat;
import org.opencv.imgcodecs.Imgcodecs;

import java.util.concurrent.Callable;

public class FaceDetectTask implements Callable<Integer> {

    /** 人脸照片地址*/
    private String path;

    public FaceDetectTask(String path) {
        this.path=path;
    }

    /** 人脸检测校验*/
    @Override
    public Integer call() throws Exception {
        Mat mat = Imgcodecs.imread(path);
        if (mat.empty()) {
            System.out.println("image not exist or empty");
            return 0;
        }
        long matAddr = mat.getNativeObjAddr();
        // type 0: 表示rgb 人脸检测 1:表示nir人脸检测
        int type = 0;
        return FaceUtil.detect(matAddr, type);// 这个是上面自定义封装的
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

调用

	// 人脸检测
    FaceDetectTask detectTask = new FaceDetectTask(path);// path图片路径
    Future<Integer> future = pool.submit(detectTask);
    Integer detect = 0;
    while (true){// 防止没有执行完返回空值
        if (future.isDone()){
            detect = future.get();
            break;
        }
    }
    if (detect == 0) {
        remarks = "照片没有检测到人脸-注册失败";
    } else if (detect == 1) {
        remarks = "照片检测到多张人脸-注册失败";
    } else {
    	// 逻辑处理
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

其他

定制化说明

检测多人脸

一张照片多人脸检测,默认只会返回一条记录,这个时候就需要定制化了。
1、将SDK目录下的conf文件夹名称改为config;
2、然后api.sdkInit(“F:\SDK”),初始化模型路径需要改成绝对路径,不然不生效,不知道为啥不能用空字符串(也就是当前目录)
3、根据对应使用修改config目录下的json文件的值(参考官方文档“能力定制化说明”)

模型路径指向

把models文件夹丢到F:\SDK,初始化的时候使用:api.sdkInit(“F:\SDK”)

激活指向

把license文件夹丢到F:\SDK,初始化的时候使用:api.sdkInit(“F:\SDK”)

说明
1、将这三个文件包丢到同一个目录下,然后初始化的时候一步加载完成
2、Windows下文件夹路径使用双斜杠,这里只显示单斜杠而已
3、如果觉得项目下太多文件,可以把config、models、license这三个文件夹单独拎出来放到一个文件夹里(如,放到“F:\SDK”下,像上面那样初始化设置路径即可);还有dll文件开发时可以把全部丢到 C:\Program Files\Java\jdk1.8.0_181\bin 下,这样就看起来整洁了许多,dll发布到时候再丢到 C:\Program Files\Java\jre1.8.0_181\bin 即可

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/938223
推荐阅读
相关标签
  

闽ICP备14008679号