Java使用JNA呼叫C的SDK
阿新 • • 發佈:2019-01-05
案例中用到的jar包,javacv1.2,opencv3.0
java模仿c的結構體,儲存身份證資訊
下面這個是獲取人臉圖片資訊的package com.aast.service; import java.util.ArrayList; import java.util.List; import com.sun.jna.*; /** * C++ 獲取身份證資訊的介面 * @author Administrator */ public interface Termb extends Library{ public static class IdCardTxtInfo extends Structure{ public byte[] name=new byte[31]; public byte[] sex=new byte[6]; public byte[] nation=new byte[11]; public byte[] borndate=new byte[9]; public byte[] address=new byte[71]; public byte[] idno=new byte[19]; public byte[] department=new byte[31]; public byte[] StartDate=new byte[9]; public byte[] EndDate=new byte[9]; public byte[] Reserve=new byte[37]; public byte[] AppAddress=new byte[71]; public byte[] PhotoBMP=new byte[1024*10]; @Override protected List<String> getFieldOrder() { List<String> list=new ArrayList<>(); list.add("name"); list.add("sex"); list.add("nation"); list.add("borndate"); list.add("address"); list.add("idno"); list.add("department"); list.add("StartDate"); list.add("EndDate"); list.add("Reserve"); list.add("AppAddress"); list.add("PhotoBMP"); return list; } } public int InitFilePath(String fname); public int InitComm(int iPort); public int Authenticate(); public int Read_Content(int iActive); public int GetIdCardTxtInfo(IdCardTxtInfo result); public int CloseComm(); }
C的結構體
//(1) 人臉位置,圖片中人臉的位置資訊 typedef struct { long nTop;//上 long nLeft; //左 long nRight; //右 long nBottom; //下 float score;//人臉質量,範圍:0-100 ,數值越高質量越好 char szPhotoPath[MAX_PATH];//人臉截圖路徑 }FaceInfo; //(2)特徵值,圖片中人臉的特徵值資訊 typedef struct { float pmodel[1280]; //特徵值陣列 long model_size; //陣列大小 }FaceModelInfo; //(3)一張圖片整體資訊 typedef struct { BOOL bNeedPhoto; //是否要保留人臉截圖 FaceInfo faceInfo[4];//人臉資訊 FaceModelInfo faceModelInfo[4];//人臉特徵資訊 int nFacesize;//有多少個人臉 }FaceCheckInfo;
package com.aast.service; import java.util.Arrays; import java.util.List; import com.sun.jna.*; import com.sun.jna.ptr.FloatByReference; import com.sun.jna.win32.*; public interface Camera extends StdCallLibrary{ public class FaceInfo extends Structure{ public NativeLong nTop; //上 public NativeLong nLeft; //左 public NativeLong nRight; //右 public NativeLong nBottom;//下 public float score; //人臉質量,範圍:0-100 ,數值越高質量越好 public byte[] szPhotoPath=new byte[260];//人臉截圖路徑 public static class ByReference extends FaceInfo implements Structure.ByReference { } public static class ByValue extends FaceInfo implements Structure.ByValue{ } @Override protected List<String> getFieldOrder(){ return Arrays.asList(new String[]{"nTop", "nLeft", "nRight", "nBottom","score","szPhotoPath"}); } @Override public String toString() { return "FaceInfo [nTop=" + nTop + ", nLef=" + nLeft + ", nRight=" + nRight + ", nBottom=" + nBottom + ", score=" + score + ", szPhotoPath=" + szPhotoPath;//Arrays.toString(szPhotoPath) + "]"; } } public class FaceModelInfo extends Structure{ public float[] pmodel=new float[1280]; //特徵值陣列 public NativeLong model_size; //陣列大小 public static class ByReference extends FaceModelInfo implements Structure.ByReference { } public static class ByValue extends FaceModelInfo implements Structure.ByValue{ } @Override protected List<String> getFieldOrder(){ return Arrays.asList(new String[]{"pmodel","model_size"}); } @Override public String toString() { return "FaceModelInfo [pmodel=" + Arrays.toString(pmodel) + ", model_size=" + model_size + "]"; } } public class FaceCheckInfo extends Structure{ public byte bNeedPhoto; //是否要保留人臉截圖 public FaceInfo[] faceInfo=new FaceInfo[4]; public FaceModelInfo[] faceModelInfo=new FaceModelInfo[4]; public int nFacesize;//有多少個人臉 public static class ByReference extends FaceCheckInfo implements Structure.ByReference { } public static class ByValue extends FaceCheckInfo implements Structure.ByValue{ } @Override protected List<String> getFieldOrder(){ return Arrays.asList(new String[]{"bNeedPhoto", "faceInfo", "faceModelInfo", "nFacesize"}); } @Override public String toString() { return "FaceCheckInfo [bNeedPhoto=" + bNeedPhoto + ", faceInfo=" + Arrays.toString(faceInfo) + ", faceModelInfo=" + Arrays.toString(faceModelInfo) + ", nFacesize=" + nFacesize + "]"; } } boolean InitSDK(String path);//初始化SDK,一個應用程式只初始化一次,一般在應用啟動時,TRUE為成功,FASE為失敗 int DetectFace(byte[] pImageBuf,int nImageLen,FaceCheckInfo.ByReference faceCheckInfo); boolean CalcModel(FaceModelInfo faceModelInfo1,FaceModelInfo faceModelInfo2,FloatByReference pFxd); boolean DelSDK(); }
1.java呼叫身份證SDK
package com.aast.utils;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import com.aast.entity.IdCardInfo;
import com.aast.service.Termb;
import com.sun.jna.Native;
public class IDCardSDK {
private static Termb lib=null;
private static Termb.IdCardTxtInfo info =null;
private static IdCardInfo idCardInfo=null;
private static String str;
static{
lib = (Termb) Native.loadLibrary("c:\\src\\termb", Termb.class);
}
public static String check(){
return str;
}
public static IdCardInfo start(){
if (lib.InitComm(1001) != 1){
System.out.println ("InitComm error! 讀卡器連結錯誤");
return null;
}
lib.Authenticate();//身份證授權
if (lib.Read_Content(1) != 1){
System.out.println ("Read_Content error! 身份證沒有放置好");
return null;
}
else{
try{
lib.InitFilePath("C:\\tmp\\images\\");//wlt圖片 文字路徑預設在當前資料夾
info=new Termb.IdCardTxtInfo();//初始化記憶體
lib.GetIdCardTxtInfo(info);//讀取個人資訊
idCardInfo=new IdCardInfo();//封裝個人資訊
idCardInfo.setName(new String(info.name, "gbk").trim());
idCardInfo.setSex(new String(info.sex, "gbk").trim());
idCardInfo.setNation(new String(info.nation, "gbk").trim());
idCardInfo.setBorndate(new String(info.borndate, "gbk").trim());
idCardInfo.setAddress(new String(info.address, "gbk").trim());
String id=new String(info.idno, "gbk").trim();
idCardInfo.setIdno(id);
idCardInfo.setDepartment(new String(info.department, "gbk").trim());
idCardInfo.setStartDate(new String(info.StartDate, "gbk").trim());
idCardInfo.setEndDate(new String(info.EndDate, "gbk").trim());
idCardInfo.setReserve(new String(info.Reserve, "gbk").trim());
idCardInfo.setAppAddress(new String(info.AppAddress, "gbk").trim());
idCardInfo.setPhotoBMP(getPhoto(id));
}catch(IOException e){
System.out.println("讀取身份證資訊失敗!");
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}finally {
//lib.CloseComm();
}
}
return idCardInfo;
}
private static byte[] getPhoto(String id) throws Exception{
File bmpfile=new File("C:\\tmp\\images\\"+id+".bmp");
File txtfile=new File("C:\\tmp\\images\\"+id+".txt");
if(!bmpfile.exists()){
return null;
}
if(bmpfile.exists()){
txtfile.delete();//刪除文字
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int)bmpfile.length());
BufferedInputStream in = null;
try{
in = new BufferedInputStream(new FileInputStream(bmpfile));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while((len = in.read(buffer,0,buf_size))!=-1){
bos.write(buffer,0,len);
}
return bos.toByteArray();
}catch (IOException e) {
e.printStackTrace();
throw e;
}finally{
try{
in.close();
bmpfile.delete();//刪除影象
}catch (IOException e) {
e.printStackTrace();
}
bos.close();
}
}
}
呼叫獲取人臉資訊,以及人臉比對
package com.aast.utils;
import com.aast.service.Camera;
import com.aast.service.Camera.FaceCheckInfo;
import com.aast.service.Camera.FaceInfo;
import com.aast.service.Camera.FaceModelInfo;
import com.sun.jna.Native;
import com.sun.jna.ptr.FloatByReference;
public class FaceCheckSDK {
private static FaceCheckInfo.ByReference faceCheckInfo=null;
private static FaceCheckInfo.ByReference faceCheckInfo1=null;
private static Camera INSTANCE =null;
private static String rootPath =null;
private static FloatByReference xsd=new FloatByReference(0);
static{
INSTANCE= (Camera) Native.loadLibrary("c:\\src\\FaceSDKV2", Camera.class);
rootPath= "c:\\src\\" ;
INSTANCE.InitSDK(rootPath);
}
/**進行人臉比對
* @param pImageBuf 身份證照片byte[]
* @param imgPath2 攝像頭截圖路徑
* @return
*/
public static float startCompare(FaceCheckInfo.ByReference faceCheckInfo,byte[] pImgBuf){
faceCheckInfo1=initFaceCheckInfo();
INSTANCE.DetectFace(pImgBuf, pImgBuf.length, faceCheckInfo1);
boolean b=INSTANCE.CalcModel(faceCheckInfo.faceModelInfo[0],faceCheckInfo1.faceModelInfo[0],xsd);
return xsd.getValue();
}
/**給結構體分配記憶體
* @return
*/
private static FaceCheckInfo.ByReference initFaceCheckInfo(){
FaceCheckInfo.ByReference faceCheckInfo=new FaceCheckInfo.ByReference();
for(int i=0;i<faceCheckInfo.faceInfo.length;i++)
faceCheckInfo.faceInfo[i]=new FaceInfo();
for(int i=0;i<faceCheckInfo.faceModelInfo.length;i++)
faceCheckInfo.faceModelInfo[i]=new FaceModelInfo();
return faceCheckInfo;
}
/**獲取身份證照片資訊
* @param pImgBuf
* @return
*/
public static FaceCheckInfo.ByReference getIdcardFaceInfo(byte[] pImgBuf){
FaceCheckInfo.ByReference faceCheckInfo=initFaceCheckInfo();
INSTANCE.DetectFace(pImgBuf, pImgBuf.length, faceCheckInfo);
return faceCheckInfo;
}
}
上面包含結構體巢狀 ,以及結構體陣列的問題
附上C-JAVA對應的資料,boolean 和int 好像都可互相轉換,這裡測試沒什麼問題