001// ______________________________________________________
002// Generated by codegen - https://gitee.com/l0km/codegen 
003// template: decorator/spring.controller.class.vm
004// ______________________________________________________
005/**
006 * decorator pattern 装饰者模式代理{@link FaceApi}接口<br>
007 * 将{@link FaceApi}实例封装为一个spring controler<br>
008 * 计算机生成代码(generated by automated tools DecoratorGenerator @author guyadong)<br>
009 * @author guyadong
010 *
011 */
012package net.gdface.sdk;
013import java.io.File;
014import java.io.InputStream;
015import java.net.URL;
016import java.nio.ByteBuffer;
017import java.util.List;
018import java.util.Map;
019import net.gdface.image.ImageErrorException;
020import net.gdface.image.MatType;
021import java.util.ServiceLoader;
022import java.io.PrintWriter;
023import java.io.StringWriter;
024import java.util.Iterator;
025import java.util.Objects;
026
027import org.slf4j.Logger;
028import org.slf4j.LoggerFactory;
029import org.springframework.web.bind.annotation.*;
030import io.swagger.annotations.*;
031
032/**
033 * 人脸识别SDK核心接口<br>
034 * 此接口中mat前缀的方法图像数据参数为图像矩阵(要求图像宽高必须为偶数),
035 * 其他方法中所有byte[]类型的图像参数都指未解码的图像格式(如jpg,bmp,png...),<br>
036 * 目前支持的图像格式类型依赖于JDK的支持能力
037 * @author guyadong
038 */
039@RestController
040@Api(value="FaceApi",tags={"FaceApi Controller"})
041public class FaceApiSpringController {
042    private static final Logger logger = LoggerFactory.getLogger(FaceApiSpringController.class);
043    private static InstanceSupplier instanceSupplier = getInstanceSupplier();
044    private final ResponseFactory responseFactory = loadResponseFactory();
045    /**
046     * SPI(Service Provider Interface)机制加载 {@link InstanceSupplier}实例,没有找到则返回{@code null},
047     * 返回{@link InstanceSupplier}提供的{@link FaceApi}实例
048     * @return 返回{@link FaceApi}实例
049     */
050    private static final InstanceSupplier getInstanceSupplier() {
051            /* SPI(Service Provider Interface)机制加载 {@link InstanceSupplier}实例,没有找到则抛出异常 */
052            ServiceLoader<InstanceSupplier> providers = ServiceLoader.load(InstanceSupplier.class);
053            Iterator<InstanceSupplier> itor = providers.iterator();
054            return itor.hasNext() ? itor.next() : null;
055    }
056    /**
057         * @param instanceSupplier 要设置的 instanceSupplier
058         */
059        public static void setInstanceSupplier(InstanceSupplier instanceSupplier) {
060                FaceApiSpringController.instanceSupplier = instanceSupplier;
061        }
062    /**
063     * SPI(Service Provider Interface)加载{@link ResponseFactory}接口实例,
064     * 没有找到则返回{@link DefaultResponseFactory}实例
065     * @return 返回{@link ResponseFactory}实例
066     */
067    private static final ResponseFactory loadResponseFactory() {
068            ServiceLoader<ResponseFactory> providers = ServiceLoader.load(ResponseFactory.class);
069            Iterator<ResponseFactory> itor = providers.iterator();
070            return itor.hasNext() ? itor.next() : new DefaultResponseFactory();
071    }  
072    public FaceApiSpringController() {
073    }
074
075    /**
076     * @return 返回被装饰的{@link FaceApi}实例
077     */
078    protected FaceApi delegate() {
079        return Objects.requireNonNull(
080                instanceSupplier == null ? null : instanceSupplier.instanceOfFaceApi(),
081                "FaceApi  instance is null"    );
082    }
083    // port-1
084    /**
085     * 对人脸图像提取特征码,返回比较相似度结果<br>
086     * imgData1和imgData2相等或imgData2为{@code null}时,即比较同一张图像中的两张人脸的相似度
087     * 调用该方法时假设图像({@code imgData1}和{@code imgData2})能正常解码,<br>
088     * 所以当对图像解码出现异常时,将{@link ImageErrorException}异常对象封装到{@link RuntimeException}抛出<br>
089     * 任何参数为{@code null}则抛出{@link IllegalArgumentException}
090     * @param imgData1
091     *  图像1数据(jpg,png...)字节数组
092     * @param facePos1
093     * 检测到的人脸/眼睛位置
094     * @param imgData2
095     *  图像1数据(jpg,png...)字节数组
096     * @param facePos2
097     * 检测到的人脸/眼睛位置
098     * @return 两张人脸之间的相似度(0.0~1)
099     * @throws NotFaceDetectedException
100     * @throws ImageErrorException
101     * @see #getCodeInfo(byte[], int, CodeInfo[])
102     * @see #compareCode(byte[], byte[])
103     */
104    @ResponseBody
105    @RequestMapping(value = "/FaceApi/compare2Face", method = RequestMethod.POST)
106    @ApiOperation(value = "对人脸图像提取特征码,返回比较相似度结果<br>", notes = "对人脸图像提取特征码,返回比较相似度结果<br>  \n"
107+" imgData1和imgData2相等或imgData2为{@code null}时,即比较同一张图像中的两张人脸的相似度  \n"
108+" 调用该方法时假设图像({@code imgData1}和{@code imgData2})能正常解码,<br>  \n"
109+" 所以当对图像解码出现异常时,将{@link ImageErrorException}异常对象封装到{@link RuntimeException}抛出<br>  \n"
110+" 任何参数为{@code null}则抛出{@link IllegalArgumentException}",httpMethod="POST")
111    public Response compare2Face( @RequestBody Compare2FaceArgs args) 
112    {
113            Response response = responseFactory.newFaceApiResponse();
114            try{
115                response.onComplete(delegate().compare2Face(args.imgData1,args.facePos1,args.imgData2,args.facePos2));
116            }
117            catch(Exception e){
118                logger.error(e.getMessage(),e);
119                response.onError(e);
120            }
121            return response;
122    }
123    // port-2
124    /**
125     * 特征码比对<br>
126     * 参数为{@code null}或长度不一致则抛出{@link IllegalArgumentException}异常,返回两个特征码之间的相似度(0.0~1)
127     * @param code1 待比对的特征码
128     * @param code2 待比对的特征码
129     * @return 相似度(0.0~1)
130     */
131    @ResponseBody
132    @RequestMapping(value = "/FaceApi/compareCode", method = RequestMethod.POST)
133    @ApiOperation(value = "特征码比对<br>", notes = "特征码比对<br>  \n"
134+" 参数为{@code null}或长度不一致则抛出{@link IllegalArgumentException}异常,返回两个特征码之间的相似度(0.0~1)",httpMethod="POST")
135    public Response compareCode( @RequestBody CompareCodeArgs args) 
136    {
137            Response response = responseFactory.newFaceApiResponse();
138            try{
139                response.onComplete(delegate().compareCode(args.code1,args.code2));
140            }
141            catch(Exception e){
142                logger.error(e.getMessage(),e);
143                response.onError(e);
144            }
145            return response;
146    }
147    // port-3
148    /**
149     * 特征码比对1:N<br>
150     * 返回对应的特征码相似度数组
151     * @param code1 待比对的特征码
152     * @param codes 包含人脸特征的{@link CodeInfo }数组
153     * @return 特征码相似度数组
154     */
155    @ResponseBody
156    @RequestMapping(value = "/FaceApi/compareCodes", method = RequestMethod.POST)
157    @ApiOperation(value = "特征码比对1:N<br>", notes = "特征码比对1:N<br>  \n"
158+" 返回对应的特征码相似度数组",httpMethod="POST")
159    public Response compareCodes( @RequestBody CompareCodesArgs args) 
160    {
161            Response response = responseFactory.newFaceApiResponse();
162            try{
163                response.onComplete(delegate().compareCodes(args.code1,args.codes));
164            }
165            catch(Exception e){
166                logger.error(e.getMessage(),e);
167                response.onError(e);
168            }
169            return response;
170    }
171    // port-4
172    /**
173     * 特征码比对1:N<br>
174     * 对{@code imgData}图像数据检测人脸并提取特征,然后与{@code code}特征进行比对,
175     * 返回包含比对相似度结果的{@link CompareResult}实例
176     * @param code 人脸特征数据
177     * @param imgData 待比对的图像(jpg,png...)(可能有多张人脸)
178     * @param faceNum  参见 {@link #getCodeInfo(byte[], int, CodeInfo[])}
179     * @return {@link CompareResult}实例
180     * @throws NotFaceDetectedException 没有检测到人脸
181     * @throws ImageErrorException
182     * @see #compareCodes(byte[], CodeInfo[])
183     * @see #detectAndGetCodeInfo(byte[], int)
184     */
185    @ResponseBody
186    @RequestMapping(value = "/FaceApi/compareFaces", method = RequestMethod.POST)
187    @ApiOperation(value = "特征码比对1:N<br>", notes = "特征码比对1:N<br>  \n"
188+" 对{@code imgData}图像数据检测人脸并提取特征,然后与{@code code}特征进行比对,  \n"
189+" 返回包含比对相似度结果的{@link CompareResult}实例",httpMethod="POST")
190    public Response compareFaces( @RequestBody CompareFacesArgs args) 
191    {
192            Response response = responseFactory.newFaceApiResponse();
193            try{
194                response.onComplete(delegate().compareFaces(args.code,args.imgData,args.faceNum));
195            }
196            catch(Exception e){
197                logger.error(e.getMessage(),e);
198                response.onError(e);
199            }
200            return response;
201    }
202    // port-5
203    /**
204     * 特征码比对1:N<br>
205     * @param code1 人脸特征数据
206     * @param codes 一组人脸特征
207     * @return 返回对应的特征码相似度列表
208     */
209    @ResponseBody
210    @RequestMapping(value = "/FaceApi/compareFeatures", method = RequestMethod.POST)
211    @ApiOperation(value = "特征码比对1:N<br>", notes = "特征码比对1:N<br>",httpMethod="POST")
212    public Response compareFeatures( @RequestBody CompareFeaturesArgs args) 
213    {
214            Response response = responseFactory.newFaceApiResponse();
215            try{
216                response.onComplete(delegate().compareFeatures(args.code1,args.codes));
217            }
218            catch(Exception e){
219                logger.error(e.getMessage(),e);
220                response.onError(e);
221            }
222            return response;
223    }
224    // port-6
225    /**
226     * 对两个图像指定范围({@link FRect})进行人脸检测,找到并提取唯一的人脸特征码,然后比较相似度,返回相似度结果<br>
227     * imgData1和imgData2相等或imgData2为{@code null}时,
228     * 即比较同一张图像中的两张人脸的相似度,这种情况下detectRect1和detectRect2都不能为{@code null}<br>
229     * imgData1和imgData2不相等且都不为{@code null}时,detectRect1和detectRect2被忽略
230     * @param imgData1
231     * 图像1数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
232     * @param detectRect1
233     * 图片检测范围,为null时全图检测
234     * @param imgData2
235     * 图像2数据(jpg,png...)字节数组
236     * @param detectRect2
237     * 图片检测范围,为null时全图检测
238     * @return 两张人脸之间的相似度(0.0~1)
239     * @throws ImageErrorException
240     * @throws NotFaceDetectedException
241     * @see #detectAndGetCodeInfo(byte[], int)
242     * @see #compareCode(byte[], byte[])
243     */
244    @ResponseBody
245    @RequestMapping(value = "/FaceApi/detectAndCompare2Face", method = RequestMethod.POST)
246    @ApiOperation(value = "对两个图像指定范围({@link FRect})进行人脸检测,找到并提取唯一的人脸特征码,然后比较相似度,返回相似度结果<br>", notes = "对两个图像指定范围({@link FRect})进行人脸检测,找到并提取唯一的人脸特征码,然后比较相似度,返回相似度结果<br>  \n"
247+" imgData1和imgData2相等或imgData2为{@code null}时,  \n"
248+" 即比较同一张图像中的两张人脸的相似度,这种情况下detectRect1和detectRect2都不能为{@code null}<br>  \n"
249+" imgData1和imgData2不相等且都不为{@code null}时,detectRect1和detectRect2被忽略",httpMethod="POST")
250    public Response detectAndCompare2Face( @RequestBody DetectAndCompare2FaceArgs args) 
251    {
252            Response response = responseFactory.newFaceApiResponse();
253            try{
254                response.onComplete(delegate().detectAndCompare2Face(args.imgData1,args.detectRect1,args.imgData2,args.detectRect2));
255            }
256            catch(Exception e){
257                logger.error(e.getMessage(),e);
258                response.onError(e);
259            }
260            return response;
261    }
262    // port-7
263    /**
264     * 先对图像数据{@code imgData}进行人脸检测,然后提取人脸特征码<br>
265     * 返回所有成功提取特征码的{@link CodeInfo}数组,
266     * 与{@link #getCodeInfo(byte[], int, CodeInfo[])}的返回结果有差别,返回结果中不包含检测到人脸但提取特征码失败的对象
267     * @param imgData
268     * 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
269     * @param faceNum
270     * 参见 {@link #getCodeInfo(byte[], int, CodeInfo[])}
271     * @return {@link CodeInfo}数组<br>
272     * @throws ImageErrorException
273     * @throws NotFaceDetectedException 没有检测人脸或提取到特征码的人脸数目不是要求的人脸数目(faceNum>0)
274     */
275    @ResponseBody
276    @RequestMapping(value = "/FaceApi/detectAndGetCodeInfo", method = RequestMethod.POST)
277    @ApiOperation(value = "先对图像数据{@code imgData}进行人脸检测,然后提取人脸特征码<br>", notes = "先对图像数据{@code imgData}进行人脸检测,然后提取人脸特征码<br>  \n"
278+" 返回所有成功提取特征码的{@link CodeInfo}数组,  \n"
279+" 与{@link #getCodeInfo(byte[], int, CodeInfo[])}的返回结果有差别,返回结果中不包含检测到人脸但提取特征码失败的对象",httpMethod="POST")
280    public Response detectAndGetCodeInfo( @RequestBody DetectAndGetCodeInfoArgs args) 
281    {
282            Response response = responseFactory.newFaceApiResponse();
283            try{
284                response.onComplete(delegate().detectAndGetCodeInfo(args.imgData,args.faceNum));
285            }
286            catch(Exception e){
287                logger.error(e.getMessage(),e);
288                response.onError(e);
289            }
290            return response;
291    }
292    // port-8
293    /**
294     * 检测最中心的人脸<br>
295     * 返回人脸位置数据对象{@link CodeInfo}
296     * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
297     * @return {@link CodeInfo}
298     * @throws NotFaceDetected 没有检测到人脸
299     * @throws ImageError 图像读取错误
300     */
301    @ResponseBody
302    @RequestMapping(value = "/FaceApi/detectCenterFace", method = RequestMethod.POST)
303    @ApiOperation(value = "检测最中心的人脸<br>", notes = "检测最中心的人脸<br>  \n"
304+" 返回人脸位置数据对象{@link CodeInfo}",httpMethod="POST")
305    public Response detectCenterFace( @RequestBody DetectCenterFaceArgs args) 
306    {
307            Response response = responseFactory.newFaceApiResponse();
308            try{
309                response.onComplete(delegate().detectCenterFace(args.imgData));
310            }
311            catch(Exception e){
312                logger.error(e.getMessage(),e);
313                response.onError(e);
314            }
315            return response;
316    }
317    // port-9
318    /**
319     * 对图像({@code imgData})进行人脸检测,返回人脸位置数据对象{@link CodeInfo}数组<br>
320     * 没有检测到人脸则返回空数组
321     * @param imgData
322     * 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
323     * @return {@link CodeInfo}数组
324     * @throws ImageErrorException 图像读取错误
325     */
326    @ResponseBody
327    @RequestMapping(value = "/FaceApi/detectFace", method = RequestMethod.POST)
328    @ApiOperation(value = "对图像({@code imgData})进行人脸检测,返回人脸位置数据对象{@link CodeInfo}数组<br>", notes = "对图像({@code imgData})进行人脸检测,返回人脸位置数据对象{@link CodeInfo}数组<br>  \n"
329+" 没有检测到人脸则返回空数组",httpMethod="POST")
330    public Response detectFace( @RequestBody DetectFaceArgs args) 
331    {
332            Response response = responseFactory.newFaceApiResponse();
333            try{
334                response.onComplete(delegate().detectFace(args.imgData));
335            }
336            catch(Exception e){
337                logger.error(e.getMessage(),e);
338                response.onError(e);
339            }
340            return response;
341    }
342    // port-10
343    /**
344     * 检测最大的人脸<br>
345     * 返回人脸位置数据对象{@link CodeInfo}
346     * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
347     * @return {@link CodeInfo}
348     * @throws NotFaceDetected 没有检测到人脸
349     * @throws ImageError 图像读取错误
350     */
351    @ResponseBody
352    @RequestMapping(value = "/FaceApi/detectMaxFace", method = RequestMethod.POST)
353    @ApiOperation(value = "检测最大的人脸<br>", notes = "检测最大的人脸<br>  \n"
354+" 返回人脸位置数据对象{@link CodeInfo}",httpMethod="POST")
355    public Response detectMaxFace( @RequestBody DetectMaxFaceArgs args) 
356    {
357            Response response = responseFactory.newFaceApiResponse();
358            try{
359                response.onComplete(delegate().detectMaxFace(args.imgData));
360            }
361            catch(Exception e){
362                logger.error(e.getMessage(),e);
363                response.onError(e);
364            }
365            return response;
366    }
367    // port-11
368    /**
369     * 根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br>
370     * 与 {@link #detectAndGetCodeInfo(byte[], int)}不同, 本方法不对图像数据{@code imgData}进行人脸检测,<br>
371     * 假设{@code facePos}是 {@link #detectFace(byte[])}或 {@link #detectFaceAgain(byte[], FRect[])} 的返回结果<br>
372     * 返回facePos,如果没有提取到特征码,则对应元素{@link CodeInfo#getCode()}返回{@code null}
373     * @param imgData
374     * 图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException}
375     * @param faceNum
376     * 要求返回的人脸特征码数目<br>
377     * 大于0时,如果实际提取到的人脸特征码数目不等于{@code faceNum},则抛出{@link NotFaceDetectedException}<br>
378     * 小于等于0时,返回所有提取到到人脸特征码
379     * @param facePos
380     * 检测到的人脸位置对象列表<br>
381     * 为{@code null}或数组长度为0时抛出{@link IllegalArgumentException}<br>
382     * 如果元素为{@code null},则跳过<br>
383     * @return 返回facePos
384     * @throws NotFaceDetectedException 提取特征码的人脸数目为0或没有提取到指定数目(faceNum大于0时)的特征码
385     */
386    @ResponseBody
387    @RequestMapping(value = "/FaceApi/getCodeInfo", method = RequestMethod.POST)
388    @ApiOperation(value = "根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br>", notes = "根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br>  \n"
389+" 与 {@link #detectAndGetCodeInfo(byte[], int)}不同, 本方法不对图像数据{@code imgData}进行人脸检测,<br>  \n"
390+" 假设{@code facePos}是 {@link #detectFace(byte[])}或 {@link #detectFaceAgain(byte[], FRect[])} 的返回结果<br>  \n"
391+" 返回facePos,如果没有提取到特征码,则对应元素{@link CodeInfo#getCode()}返回{@code null}",httpMethod="POST")
392    public Response getCodeInfo( @RequestBody GetCodeInfoArgs args) 
393    {
394            Response response = responseFactory.newFaceApiResponse();
395            try{
396                response.onComplete(delegate().getCodeInfo(args.imgData,args.faceNum,args.facePos));
397            }
398            catch(Exception e){
399                logger.error(e.getMessage(),e);
400                response.onError(e);
401            }
402            return response;
403    }
404    // port-12
405    /**
406     * 根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br>
407     * 返回包含人脸特征的{@link CodeInfo}对象,提取特征失败则返回{@code null}
408     * @param imgData  图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException}
409     * @param facePos 人脸位置信息对象,为{@code null}则抛出异常
410     * @return {@link CodeInfo} or {@code null}
411     */
412    @ResponseBody
413    @RequestMapping(value = "/FaceApi/getCodeInfoSingle", method = RequestMethod.POST)
414    @ApiOperation(value = "根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br>", notes = "根据{@code facePos}提供的人脸信息位置, 在{@code imgData}图像中提取特征码<br>  \n"
415+" 返回包含人脸特征的{@link CodeInfo}对象,提取特征失败则返回{@code null}",httpMethod="POST")
416    public Response getCodeInfo( @RequestBody GetCodeInfoSingleArgs args) 
417    {
418            Response response = responseFactory.newFaceApiResponse();
419            try{
420                response.onComplete(delegate().getCodeInfo(args.imgData,args.facePos));
421            }
422            catch(Exception e){
423                logger.error(e.getMessage(),e);
424                response.onError(e);
425            }
426            return response;
427    }
428    // port-13
429    /**
430     * 多张人脸提取特征(用于多张人脸合成一个特征的算法)<br>
431     * 返回人脸特征数据
432     * {@link #multiFaceFeature()}返回{@code false}时代表此方法未被实现,执行会抛出异常
433     * @param faces 人脸图像数据(jpg,png...)与人脸位置信息对象的映射
434     * @return 人脸特征数据
435     * @throws NotFaceDetectedException
436     */
437    @ResponseBody
438    @RequestMapping(value = "/FaceApi/getFeature", method = RequestMethod.POST)
439    @ApiOperation(value = "多张人脸提取特征(用于多张人脸合成一个特征的算法)<br>", notes = "多张人脸提取特征(用于多张人脸合成一个特征的算法)<br>  \n"
440+" 返回人脸特征数据  \n"
441+" {@link #multiFaceFeature()}返回{@code false}时代表此方法未被实现,执行会抛出异常",httpMethod="POST")
442    public Response getFeature( @RequestBody GetFeatureArgs args) 
443    {
444            Response response = responseFactory.newFaceApiResponse();
445            try{
446                response.onComplete(delegate().getFeature(args.faces));
447            }
448            catch(Exception e){
449                logger.error(e.getMessage(),e);
450                response.onError(e);
451            }
452            return response;
453    }
454    // port-14
455    /**
456     * 判断图像是否能提取到人脸特征码<br>
457     * 为{@code true}则能检测到人脸并能提取特征码
458     * @param imgData
459     * 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
460     * @return 为{@code true}则能检测到人脸并能提取特征码
461     * @throws ImageErrorException
462     * @see #detectAndGetCodeInfo(byte[], int)
463     */
464    @ResponseBody
465    @RequestMapping(value = "/FaceApi/hasFace", method = RequestMethod.POST)
466    @ApiOperation(value = "判断图像是否能提取到人脸特征码<br>", notes = "判断图像是否能提取到人脸特征码<br>  \n"
467+" 为{@code true}则能检测到人脸并能提取特征码",httpMethod="POST")
468    public Response hasFace( @RequestBody HasFaceArgs args) 
469    {
470            Response response = responseFactory.newFaceApiResponse();
471            try{
472                response.onComplete(delegate().hasFace(args.imgData));
473            }
474            catch(Exception e){
475                logger.error(e.getMessage(),e);
476                response.onError(e);
477            }
478            return response;
479    }
480    // port-15
481    /**
482     * 返回当前接口实现方式<br> 
483     * false WebService类型<br>
484     * true 本地实现
485     * @return boolean
486     */
487    @ResponseBody
488    @RequestMapping(value = "/FaceApi/isLocal", method = RequestMethod.POST)
489    @ApiOperation(value = "返回当前接口实现方式<br> ", notes = "返回当前接口实现方式<br>   \n"
490+" false WebService类型<br>  \n"
491+" true 本地实现",httpMethod="POST")
492    public Response isLocal() 
493    {
494            Response response = responseFactory.newFaceApiResponse();
495            try{
496                response.onComplete(false);
497            }
498            catch(Exception e){
499                logger.error(e.getMessage(),e);
500                response.onError(e);
501            }
502            return response;
503    }
504    // port-16
505    /**
506     * 先对图像矩阵数据{@code imgData}进行人脸检测,然后提取人脸特征码<br>
507     * 返回包含人脸特征数据的{@code CodeInfo}数组
508     * @param matType 图像矩阵类型
509     * @param matData 图像矩阵
510     * @param width 图像宽度
511     * @param height 图像高度
512     * @param faceNum 参见 {@link #getCodeInfo(byte[], int, CodeInfo[])}
513     * @return {@code CodeInfo}数组
514     * @throws NotFaceDetectedException
515     * @since 2.1.9
516     */
517    @ResponseBody
518    @RequestMapping(value = "/FaceApi/matDetectAndGetCodeInfo", method = RequestMethod.POST)
519    @ApiOperation(value = "先对图像矩阵数据{@code imgData}进行人脸检测,然后提取人脸特征码<br>", notes = "先对图像矩阵数据{@code imgData}进行人脸检测,然后提取人脸特征码<br>  \n"
520+" 返回包含人脸特征数据的{@code CodeInfo}数组",httpMethod="POST")
521    public Response matDetectAndGetCodeInfo( @RequestBody MatDetectAndGetCodeInfoArgs args) 
522    {
523            Response response = responseFactory.newFaceApiResponse();
524            try{
525                response.onComplete(delegate().matDetectAndGetCodeInfo(args.matType,args.matData,args.width,args.height,args.faceNum));
526            }
527            catch(Exception e){
528                logger.error(e.getMessage(),e);
529                response.onError(e);
530            }
531            return response;
532    }
533    // port-17
534    /**
535     * 对图像矩阵进行人脸检测<br>
536     * 返回人脸信息对象列表,没有检测到人脸返回空表
537     * @param matType 图像矩阵类型
538     * @param matData 图像矩阵
539     * @param width 图像宽度
540     * @param height 图像高度
541     * @return 人脸信息对象列表
542     * @since 2.1.9
543     */
544    @ResponseBody
545    @RequestMapping(value = "/FaceApi/matDetectFace", method = RequestMethod.POST)
546    @ApiOperation(value = "对图像矩阵进行人脸检测<br>", notes = "对图像矩阵进行人脸检测<br>  \n"
547+" 返回人脸信息对象列表,没有检测到人脸返回空表",httpMethod="POST")
548    public Response matDetectFace( @RequestBody MatDetectFaceArgs args) 
549    {
550            Response response = responseFactory.newFaceApiResponse();
551            try{
552                response.onComplete(delegate().matDetectFace(args.matType,args.matData,args.width,args.height));
553            }
554            catch(Exception e){
555                logger.error(e.getMessage(),e);
556                response.onError(e);
557            }
558            return response;
559    }
560    // port-18
561    /**
562     * 检测最大的人脸<br>
563     * 返回人脸位置数据对象{@link CodeInfo}
564     * @param imgData 图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}
565     * @return {@link CodeInfo}
566     * @throws NotFaceDetected 没有检测到人脸
567     * @since 2.1.9
568     */
569    @ResponseBody
570    @RequestMapping(value = "/FaceApi/matDetectMaxFace", method = RequestMethod.POST)
571    @ApiOperation(value = "检测最大的人脸<br>", notes = "检测最大的人脸<br>  \n"
572+" 返回人脸位置数据对象{@link CodeInfo}",httpMethod="POST")
573    public Response matDetectMaxFace( @RequestBody MatDetectMaxFaceArgs args) 
574    {
575            Response response = responseFactory.newFaceApiResponse();
576            try{
577                response.onComplete(delegate().matDetectMaxFace(args.matType,args.matData,args.width,args.height));
578            }
579            catch(Exception e){
580                logger.error(e.getMessage(),e);
581                response.onError(e);
582            }
583            return response;
584    }
585    // port-19
586    /**
587     * 根据facePos提供的人脸信息位置, 在图像矩阵中提取特征码<br>
588     * 包含人脸特征数据的facePos
589     * @param matType 图像矩阵类型
590     * @param matData 图像矩阵
591     * @param width 图像宽度
592     * @param height 图像高度
593     * @param facenum 
594     * 要求返回的人脸特征码数目<br>
595     * 大于0时,如果实际提取到的人脸特征码数目不等于{@code faceNum},则抛出{@link NotFaceDetectedException}<br>
596     * 小于等于0时,返回所有提取到到人脸特征码
597     * @param facePos 人脸位置信息对象,不可为{@code null}
598     * @return always facePos
599     * @throws NotFaceDetectedException 提取特征码的人脸数目为0或没有提取到指定数目(faceNum大于0时)的特征码
600     * @since 2.1.9
601     */
602    @ResponseBody
603    @RequestMapping(value = "/FaceApi/matGetCodeInfo", method = RequestMethod.POST)
604    @ApiOperation(value = "根据facePos提供的人脸信息位置, 在图像矩阵中提取特征码<br>", notes = "根据facePos提供的人脸信息位置, 在图像矩阵中提取特征码<br>  \n"
605+" 包含人脸特征数据的facePos",httpMethod="POST")
606    public Response matGetCodeInfo( @RequestBody MatGetCodeInfoArgs args) 
607    {
608            Response response = responseFactory.newFaceApiResponse();
609            try{
610                response.onComplete(delegate().matGetCodeInfo(args.matType,args.matData,args.width,args.height,args.facenum,args.facePos));
611            }
612            catch(Exception e){
613                logger.error(e.getMessage(),e);
614                response.onError(e);
615            }
616            return response;
617    }
618    // port-20
619    /**
620     * 根据{@code facePos}提供的人脸信息位置, 在图像矩阵中提取特征码<br>
621     * 返回包含人脸特征的{@link CodeInfo}对象,提取特征失败则返回{@code null}
622     * @param matType 图像矩阵类型
623     * @param matData 图像矩阵
624     * @param width 图像宽度
625     * @param height 图像高度
626     * @param facePos 人脸位置信息对象,为{@code null}则抛出异常
627     * @return {@link CodeInfo} or {@code null}
628     */
629    @ResponseBody
630    @RequestMapping(value = "/FaceApi/matGetCodeInfoSingle", method = RequestMethod.POST)
631    @ApiOperation(value = "根据{@code facePos}提供的人脸信息位置, 在图像矩阵中提取特征码<br>", notes = "根据{@code facePos}提供的人脸信息位置, 在图像矩阵中提取特征码<br>  \n"
632+" 返回包含人脸特征的{@link CodeInfo}对象,提取特征失败则返回{@code null}",httpMethod="POST")
633    public Response matGetCodeInfo( @RequestBody MatGetCodeInfoSingleArgs args) 
634    {
635            Response response = responseFactory.newFaceApiResponse();
636            try{
637                response.onComplete(delegate().matGetCodeInfo(args.matType,args.matData,args.width,args.height,args.facePos));
638            }
639            catch(Exception e){
640                logger.error(e.getMessage(),e);
641                response.onError(e);
642            }
643            return response;
644    }
645    // port-21
646    /**
647     * 判断图像矩阵是否能提取到人脸特征码<br>
648     * 返回为{@code true}则能检测到人脸并能提取特征码
649     * @param matType 图像矩阵类型
650     * @param matData 图像矩阵,为{@code null}则抛出{@link IllegalArgumentException}
651     * @param width  图像宽度
652     * @param height 图像高度
653     * @return 为{@code true}则能检测到人脸并能提取特征码
654     * @since 2.1.9
655     */
656    @ResponseBody
657    @RequestMapping(value = "/FaceApi/matHasFace", method = RequestMethod.POST)
658    @ApiOperation(value = "判断图像矩阵是否能提取到人脸特征码<br>", notes = "判断图像矩阵是否能提取到人脸特征码<br>  \n"
659+" 返回为{@code true}则能检测到人脸并能提取特征码",httpMethod="POST")
660    public Response matHasFace( @RequestBody MatHasFaceArgs args) 
661    {
662            Response response = responseFactory.newFaceApiResponse();
663            try{
664                response.onComplete(delegate().matHasFace(args.matType,args.matData,args.width,args.height));
665            }
666            catch(Exception e){
667                logger.error(e.getMessage(),e);
668                response.onError(e);
669            }
670            return response;
671    }
672    // port-22
673    /**
674     * 1:N 人脸图像搜索<br>
675     * 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。<br>
676     * 返回包含相似度计算结果的FseResult数组<br>
677     * 相似度值通过 FseResult.getSimilartys() 获取<br>
678     * 对应的人脸特征ID由 FseResult.getFeatureIds()获取<br>
679     * @param matType 图像矩阵类型
680     * @param matData 图像矩阵
681     * @param width 图像宽度
682     * @param facePos
683     * 人脸位置对象<br>
684     * 为{@code null}时,先做人脸检测再提取特征码<br>
685     * 不为{@code null}时,直接在指定的位置提取特征码<br>
686     * @param similarty 相似度阀值
687     * @param rows 最多返回的记录数目
688     * @return 包含相似度计算结果的{@link FseResult}数组<br>
689     * @since 3.0.0
690     * @throws NotFaceDetectedException -
691     * @throws ImageErrorException -
692     * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
693     * @see #getCodeInfo(byte[], int, CodeInfo[])
694     * @see #searchFeatures(byte[], double, int)
695     */
696    @ResponseBody
697    @RequestMapping(value = "/FaceApi/matSearchFaces", method = RequestMethod.POST)
698    @ApiOperation(value = "1:N 人脸图像搜索<br>", notes = "1:N 人脸图像搜索<br>  \n"
699+" 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。<br>  \n"
700+" 返回包含相似度计算结果的FseResult数组<br>  \n"
701+" 相似度值通过 FseResult.getSimilartys() 获取<br>  \n"
702+" 对应的人脸特征ID由 FseResult.getFeatureIds()获取<br>",httpMethod="POST")
703    public Response matSearchFaces( @RequestBody MatSearchFacesArgs args) 
704    {
705            Response response = responseFactory.newFaceApiResponse();
706            try{
707                response.onComplete(delegate().matSearchFaces(args.matType,args.matData,args.width,args.height,args.facePos,args.similarty,args.rows));
708            }
709            catch(Exception e){
710                logger.error(e.getMessage(),e);
711                response.onError(e);
712            }
713            return response;
714    }
715    // port-23
716    /**
717     * 检测指定的人脸是否戴口罩<br>
718     * 返回值有三种状态:
719     * <ul>
720     * <li>{@code true} 戴口罩返回</li>
721     * <li>{@code false} 未戴口罩返回</li>
722     * <li>{@code null} 不知道</li>
723     * </ul>
724     * @param matType 图像矩阵类型
725     * @param matData  图像矩阵
726     * @param width  图像宽度
727     * @param height 图像高度
728     * @param faceInfo  人脸位置信息
729     * @return 返回口罩检测结果
730     * @since 2.1.9
731     */
732    @ResponseBody
733    @RequestMapping(value = "/FaceApi/matWearMask", method = RequestMethod.POST)
734    @ApiOperation(value = "检测指定的人脸是否戴口罩<br>", notes = "检测指定的人脸是否戴口罩<br>  \n"
735+" 返回值有三种状态:  \n"
736+" <ul>  \n"
737+" <li>{@code true} 戴口罩返回</li>  \n"
738+" <li>{@code false} 未戴口罩返回</li>  \n"
739+" <li>{@code null} 不知道</li>  \n"
740+" </ul>",httpMethod="POST")
741    public Response matWearMask( @RequestBody MatWearMaskArgs args) 
742    {
743            Response response = responseFactory.newFaceApiResponse();
744            try{
745                response.onComplete(delegate().matWearMask(args.matType,args.matData,args.width,args.height,args.faceInfo));
746            }
747            catch(Exception e){
748                logger.error(e.getMessage(),e);
749                response.onError(e);
750            }
751            return response;
752    }
753    // port-24
754    /**
755     * 返回当前SDK特性(能力)描述,已定义字段:<br>
756     * <ul>
757     * <li>SDK_VERSION [string]SDK版本号</li>
758     * <li>MULTI_FACE_FEATURE [boolean]算法是否支持多人脸合成特征</li>
759     * <li>FACE_LIVE [boolean]是否支持活体检测</li>
760     * <li>WEAR_MASK [boolean]是否支持口罩检测</li>
761     * <li>FDDATA_SIZE [int]人脸检测数据的(byte)长度</li>
762     * <li>FEATURE_SIZE [int]人脸特征数据(byte)长度</li>
763     * <li>MAX_FACE_COUNT [int]最大检测人脸数目</li>
764     * <li>FSE_ENABLE [boolean]是否支持特征内存搜索引擎</li>
765     * <li>CODEINFO_RELOCATE [boolean]是否支持CodeInfo对象重定位</li>
766     * <li>LOCAL_DETECT [boolean] 人脸检测是否为本地实现,未定义则为false</li>
767     * </ul>
768     * 以上字段名常量定义参见{@link CapacityFieldConstant}
769     * @return key-value 对描述算法能力的映射
770     * @since 2.2.7
771     */
772    @ResponseBody
773    @RequestMapping(value = "/FaceApi/sdkCapacity", method = RequestMethod.POST)
774    @ApiOperation(value = "返回当前SDK特性(能力)描述,已定义字段:<br>", notes = "返回当前SDK特性(能力)描述,已定义字段:<br>  \n"
775+" <ul>  \n"
776+" <li>SDK_VERSION [string]SDK版本号</li>  \n"
777+" <li>MULTI_FACE_FEATURE [boolean]算法是否支持多人脸合成特征</li>  \n"
778+" <li>FACE_LIVE [boolean]是否支持活体检测</li>  \n"
779+" <li>WEAR_MASK [boolean]是否支持口罩检测</li>  \n"
780+" <li>FDDATA_SIZE [int]人脸检测数据的(byte)长度</li>  \n"
781+" <li>FEATURE_SIZE [int]人脸特征数据(byte)长度</li>  \n"
782+" <li>MAX_FACE_COUNT [int]最大检测人脸数目</li>  \n"
783+" <li>FSE_ENABLE [boolean]是否支持特征内存搜索引擎</li>  \n"
784+" <li>CODEINFO_RELOCATE [boolean]是否支持CodeInfo对象重定位</li>  \n"
785+" <li>LOCAL_DETECT [boolean] 人脸检测是否为本地实现,未定义则为false</li>  \n"
786+" </ul>  \n"
787+" 以上字段名常量定义参见{@link CapacityFieldConstant}",httpMethod="POST")
788    public Response sdkCapacity() 
789    {
790            Response response = responseFactory.newFaceApiResponse();
791            try{
792                response.onComplete(delegate().sdkCapacity());
793            }
794            catch(Exception e){
795                logger.error(e.getMessage(),e);
796                response.onError(e);
797            }
798            return response;
799    }
800    // port-25
801    /**
802     * 1:N 人脸图像搜索<br>
803     * 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。<br>
804     * 返回包含相似度计算结果的FseResult数组<br>
805     * 相似度值通过 FseResult.getSimilartys() 获取<br>
806     * 对应的人脸特征ID由 FseResult.getFeatureIds()获取<br>
807     * @param imgData
808     * 图片字节数组
809     * @param facePos
810     * 人脸位置对象<br>
811     * 为{@code null}时,先做人脸检测再提取特征码<br>
812     * 不为{@code null}时,直接在指定的位置提取特征码<br>
813     * @param similarty 相似度阀值
814     * @param rows 最多返回的记录数目
815     * @return 包含相似度计算结果的{@link FseResult}数组<br>
816     * @since 3.0.0
817     * @throws NotFaceDetectedException -
818     * @throws ImageErrorException -
819     * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
820     * @see #getCodeInfo(byte[], int, CodeInfo[])
821     * @see #searchFeatures(byte[], double, int)
822     */
823    @ResponseBody
824    @RequestMapping(value = "/FaceApi/searchFaces", method = RequestMethod.POST)
825    @ApiOperation(value = "1:N 人脸图像搜索<br>", notes = "1:N 人脸图像搜索<br>  \n"
826+" 对{@code facePos}指定的人脸位置提取特征码,然后在数据库中搜索相似的人脸返回搜索结果。<br>  \n"
827+" 返回包含相似度计算结果的FseResult数组<br>  \n"
828+" 相似度值通过 FseResult.getSimilartys() 获取<br>  \n"
829+" 对应的人脸特征ID由 FseResult.getFeatureIds()获取<br>",httpMethod="POST")
830    public Response searchFaces( @RequestBody SearchFacesArgs args) 
831    {
832            Response response = responseFactory.newFaceApiResponse();
833            try{
834                response.onComplete(delegate().searchFaces(args.imgData,args.facePos,args.similarty,args.rows));
835            }
836            catch(Exception e){
837                logger.error(e.getMessage(),e);
838                response.onError(e);
839            }
840            return response;
841    }
842    // port-26
843    /**
844     * 1:N 人脸特征搜索<br>
845     * 搜索与{@code code}相似度大于{@code similarty}的记录(最多返回前{@code rows}个结果)<br>
846     * 返回包含相似度计算结果的{@link FseResult}数组,返回结果以相似度降序排列<br>
847     * 相似度值通过 {@link FseResult#getSimilartys()} 获取<br>
848     * 对应的人脸特征ID由 {@link FseResult#getFeatureIds()}获取
849     * @param feature
850     * 要搜索的特征码
851     * @param similarty
852     * 相似度阀值
853     * @param rows
854     * 最多返回的记录数目
855     * @return 包含相似度计算结果的{@link FseResult}数组<br>
856     * @since 3.0.0
857     * @throws UnsupportedOperationException 没有人脸识别算法(FaceApi实例)支持
858     */
859    @ResponseBody
860    @RequestMapping(value = "/FaceApi/searchFeatures", method = RequestMethod.POST)
861    @ApiOperation(value = "1:N 人脸特征搜索<br>", notes = "1:N 人脸特征搜索<br>  \n"
862+" 搜索与{@code code}相似度大于{@code similarty}的记录(最多返回前{@code rows}个结果)<br>  \n"
863+"  返回包含相似度计算结果的{@link FseResult}数组,返回结果以相似度降序排列<br>  \n"
864+"  相似度值通过 {@link FseResult#getSimilartys()} 获取<br>  \n"
865+"  对应的人脸特征ID由 {@link FseResult#getFeatureIds()}获取",httpMethod="POST")
866    public Response searchFeatures( @RequestBody SearchFeaturesArgs args) 
867    {
868            Response response = responseFactory.newFaceApiResponse();
869            try{
870                response.onComplete(delegate().searchFeatures(args.feature,args.similarty,args.rows));
871            }
872            catch(Exception e){
873                logger.error(e.getMessage(),e);
874                response.onError(e);
875            }
876            return response;
877    }
878    // port-27
879    /**
880     * 检测指定的人脸是否戴口罩<br>
881     * 返回值有三种状态:
882     * <ul>
883     * <li>{@code true} 戴口罩返回</li>
884     * <li>{@code false} 未戴口罩返回</li>
885     * <li>{@code null} 不知道</li>
886     * </ul>
887     * @param imgData  图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException}
888     * @param faceInfo  可见光图像人脸信息
889     * @return 返回口罩检测结果
890     * @throws ImageErrorException
891     * @since 2.1.9
892     */
893    @ResponseBody
894    @RequestMapping(value = "/FaceApi/wearMask", method = RequestMethod.POST)
895    @ApiOperation(value = "检测指定的人脸是否戴口罩<br>", notes = "检测指定的人脸是否戴口罩<br>  \n"
896+" 返回值有三种状态:  \n"
897+" <ul>  \n"
898+" <li>{@code true} 戴口罩返回</li>  \n"
899+" <li>{@code false} 未戴口罩返回</li>  \n"
900+" <li>{@code null} 不知道</li>  \n"
901+" </ul>",httpMethod="POST")
902    public Response wearMask( @RequestBody WearMaskArgs args) 
903    {
904            Response response = responseFactory.newFaceApiResponse();
905            try{
906                response.onComplete(delegate().wearMask(args.imgData,args.faceInfo));
907            }
908            catch(Exception e){
909                logger.error(e.getMessage(),e);
910                response.onError(e);
911            }
912            return response;
913    }
914    /**
915     * argClass-1<br>
916     * wrap arguments for method {@link #compare2Face(Compare2FaceArgs)}
917     */
918    public static class Compare2FaceArgs{
919        @ApiModelProperty(value ="图像1数据(jpg,png...)字节数组" ,required=true ,dataType="byte[]")
920        public byte[] imgData1;
921        @ApiModelProperty(value ="检测到的人脸/眼睛位置" ,required=true ,dataType="CodeInfo")
922        public CodeInfo facePos1;
923        @ApiModelProperty(value ="图像1数据(jpg,png...)字节数组" ,required=true ,dataType="byte[]")
924        public byte[] imgData2;
925        @ApiModelProperty(value ="检测到的人脸/眼睛位置" ,required=true ,dataType="CodeInfo")
926        public CodeInfo facePos2;
927    }
928    /**
929     * argClass-2<br>
930     * wrap arguments for method {@link #compareCode(CompareCodeArgs)}
931     */
932    public static class CompareCodeArgs{
933        @ApiModelProperty(value ="待比对的特征码" ,required=true ,dataType="byte[]")
934        public byte[] code1;
935        @ApiModelProperty(value ="待比对的特征码" ,required=true ,dataType="byte[]")
936        public byte[] code2;
937    }
938    /**
939     * argClass-3<br>
940     * wrap arguments for method {@link #compareCodes(CompareCodesArgs)}
941     */
942    public static class CompareCodesArgs{
943        @ApiModelProperty(value ="待比对的特征码" ,required=true ,dataType="byte[]")
944        public byte[] code1;
945        @ApiModelProperty(value ="包含人脸特征的{@link CodeInfo }数组" ,required=true ,dataType="CodeInfo[]")
946        public CodeInfo[] codes;
947    }
948    /**
949     * argClass-4<br>
950     * wrap arguments for method {@link #compareFaces(CompareFacesArgs)}
951     */
952    public static class CompareFacesArgs{
953        @ApiModelProperty(value ="人脸特征数据" ,required=true ,dataType="byte[]")
954        public byte[] code;
955        @ApiModelProperty(value ="待比对的图像(jpg,png...)(可能有多张人脸)" ,required=true ,dataType="byte[]")
956        public byte[] imgData;
957        @ApiModelProperty(value ="参见 {@link #getCodeInfo(byte[], int, CodeInfo[])}" ,required=true ,dataType="int")
958        public int faceNum;
959    }
960    /**
961     * argClass-5<br>
962     * wrap arguments for method {@link #compareFeatures(CompareFeaturesArgs)}
963     */
964    public static class CompareFeaturesArgs{
965        @ApiModelProperty(value ="人脸特征数据" ,required=true ,dataType="byte[]")
966        public byte[] code1;
967        @ApiModelProperty(value ="一组人脸特征" ,required=true ,dataType="List")
968        public List<byte[]> codes;
969    }
970    /**
971     * argClass-6<br>
972     * wrap arguments for method {@link #detectAndCompare2Face(DetectAndCompare2FaceArgs)}
973     */
974    public static class DetectAndCompare2FaceArgs{
975        @ApiModelProperty(value ="图像1数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
976        public byte[] imgData1;
977        @ApiModelProperty(value ="图片检测范围,为null时全图检测" ,required=true ,dataType="FRect")
978        public FRect detectRect1;
979        @ApiModelProperty(value ="图像2数据(jpg,png...)字节数组" ,required=true ,dataType="byte[]")
980        public byte[] imgData2;
981        @ApiModelProperty(value ="图片检测范围,为null时全图检测" ,required=true ,dataType="FRect")
982        public FRect detectRect2;
983    }
984    /**
985     * argClass-7<br>
986     * wrap arguments for method {@link #detectAndGetCodeInfo(DetectAndGetCodeInfoArgs)}
987     */
988    public static class DetectAndGetCodeInfoArgs{
989        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
990        public byte[] imgData;
991        @ApiModelProperty(value ="参见 {@link #getCodeInfo(byte[], int, CodeInfo[])}" ,required=true ,dataType="int")
992        public int faceNum;
993    }
994    /**
995     * argClass-8<br>
996     * wrap arguments for method {@link #detectCenterFace(DetectCenterFaceArgs)}
997     */
998    public static class DetectCenterFaceArgs{
999        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1000        public byte[] imgData;
1001    }
1002    /**
1003     * argClass-9<br>
1004     * wrap arguments for method {@link #detectFace(DetectFaceArgs)}
1005     */
1006    public static class DetectFaceArgs{
1007        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1008        public byte[] imgData;
1009    }
1010    /**
1011     * argClass-10<br>
1012     * wrap arguments for method {@link #detectMaxFace(DetectMaxFaceArgs)}
1013     */
1014    public static class DetectMaxFaceArgs{
1015        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1016        public byte[] imgData;
1017    }
1018    /**
1019     * argClass-11<br>
1020     * wrap arguments for method {@link #getCodeInfo(GetCodeInfoArgs)}
1021     */
1022    public static class GetCodeInfoArgs{
1023        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1024        public byte[] imgData;
1025        @ApiModelProperty(value ="要求返回的人脸特征码数目<br>\n"
1026+"            大于0时,如果实际提取到的人脸特征码数目不等于{@code faceNum},则抛出{@link NotFaceDetectedException}<br>\n"
1027+"            小于等于0时,返回所有提取到到人脸特征码" ,required=true ,dataType="int")
1028        public int faceNum;
1029        @ApiModelProperty(value ="检测到的人脸位置对象列表<br>\n"
1030+"            为{@code null}或数组长度为0时抛出{@link IllegalArgumentException}<br>\n"
1031+"            如果元素为{@code null},则跳过<br>" ,required=true ,dataType="CodeInfo[]")
1032        public CodeInfo[] facePos;
1033    }
1034    /**
1035     * argClass-12<br>
1036     * wrap arguments for method {@link #getCodeInfo(GetCodeInfoSingleArgs)}
1037     */
1038    public static class GetCodeInfoSingleArgs{
1039        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1040        public byte[] imgData;
1041        @ApiModelProperty(value ="人脸位置信息对象,为{@code null}则抛出异常" ,required=true ,dataType="CodeInfo")
1042        public CodeInfo facePos;
1043    }
1044    /**
1045     * argClass-13<br>
1046     * wrap arguments for method {@link #getFeature(GetFeatureArgs)}
1047     */
1048    public static class GetFeatureArgs{
1049        @ApiModelProperty(value ="人脸图像数据(jpg,png...)与人脸位置信息对象的映射" ,required=true ,dataType="Map")
1050        public Map<ByteBuffer, CodeInfo> faces;
1051    }
1052    /**
1053     * argClass-14<br>
1054     * wrap arguments for method {@link #hasFace(HasFaceArgs)}
1055     */
1056    public static class HasFaceArgs{
1057        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1058        public byte[] imgData;
1059    }
1060    /**
1061     * argClass-16<br>
1062     * wrap arguments for method {@link #matDetectAndGetCodeInfo(MatDetectAndGetCodeInfoArgs)}
1063     */
1064    public static class MatDetectAndGetCodeInfoArgs{
1065        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1066        public MatType matType;
1067        @ApiModelProperty(value ="图像矩阵" ,required=true ,dataType="byte[]")
1068        public byte[] matData;
1069        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1070        public int width;
1071        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1072        public int height;
1073        @ApiModelProperty(value ="参见 {@link #getCodeInfo(byte[], int, CodeInfo[])}" ,required=true ,dataType="int")
1074        public int faceNum;
1075    }
1076    /**
1077     * argClass-17<br>
1078     * wrap arguments for method {@link #matDetectFace(MatDetectFaceArgs)}
1079     */
1080    public static class MatDetectFaceArgs{
1081        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1082        public MatType matType;
1083        @ApiModelProperty(value ="图像矩阵" ,required=true ,dataType="byte[]")
1084        public byte[] matData;
1085        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1086        public int width;
1087        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1088        public int height;
1089    }
1090    /**
1091     * argClass-18<br>
1092     * wrap arguments for method {@link #matDetectMaxFace(MatDetectMaxFaceArgs)}
1093     */
1094    public static class MatDetectMaxFaceArgs{
1095        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="MatType")
1096        public MatType matType;
1097        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="byte[]")
1098        public byte[] matData;
1099        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1100        public int width;
1101        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1102        public int height;
1103    }
1104    /**
1105     * argClass-19<br>
1106     * wrap arguments for method {@link #matGetCodeInfo(MatGetCodeInfoArgs)}
1107     */
1108    public static class MatGetCodeInfoArgs{
1109        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1110        public MatType matType;
1111        @ApiModelProperty(value ="图像矩阵" ,required=true ,dataType="byte[]")
1112        public byte[] matData;
1113        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1114        public int width;
1115        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1116        public int height;
1117        @ApiModelProperty(value ="要求返回的人脸特征码数目<br>\n"
1118+"            大于0时,如果实际提取到的人脸特征码数目不等于{@code faceNum},则抛出{@link NotFaceDetectedException}<br>\n"
1119+"            小于等于0时,返回所有提取到到人脸特征码" ,required=true ,dataType="int")
1120        public int facenum;
1121        @ApiModelProperty(value ="人脸位置信息对象,不可为{@code null}" ,required=true ,dataType="CodeInfo[]")
1122        public CodeInfo[] facePos;
1123    }
1124    /**
1125     * argClass-20<br>
1126     * wrap arguments for method {@link #matGetCodeInfo(MatGetCodeInfoSingleArgs)}
1127     */
1128    public static class MatGetCodeInfoSingleArgs{
1129        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1130        public MatType matType;
1131        @ApiModelProperty(value ="图像矩阵" ,required=true ,dataType="byte[]")
1132        public byte[] matData;
1133        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1134        public int width;
1135        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1136        public int height;
1137        @ApiModelProperty(value ="人脸位置信息对象,为{@code null}则抛出异常" ,required=true ,dataType="CodeInfo")
1138        public CodeInfo facePos;
1139    }
1140    /**
1141     * argClass-21<br>
1142     * wrap arguments for method {@link #matHasFace(MatHasFaceArgs)}
1143     */
1144    public static class MatHasFaceArgs{
1145        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1146        public MatType matType;
1147        @ApiModelProperty(value ="图像矩阵,为{@code null}则抛出{@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1148        public byte[] matData;
1149        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1150        public int width;
1151        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1152        public int height;
1153    }
1154    /**
1155     * argClass-22<br>
1156     * wrap arguments for method {@link #matSearchFaces(MatSearchFacesArgs)}
1157     */
1158    public static class MatSearchFacesArgs{
1159        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1160        public MatType matType;
1161        @ApiModelProperty(value ="图像矩阵" ,required=true ,dataType="byte[]")
1162        public byte[] matData;
1163        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1164        public int width;
1165        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1166        public int height;
1167        @ApiModelProperty(value ="人脸位置对象<br>\n"
1168+"            为{@code null}时,先做人脸检测再提取特征码<br>\n"
1169+"            不为{@code null}时,直接在指定的位置提取特征码<br>" ,required=true ,dataType="CodeInfo")
1170        public CodeInfo facePos;
1171        @ApiModelProperty(value ="相似度阀值" ,required=true ,dataType="double")
1172        public double similarty;
1173        @ApiModelProperty(value ="最多返回的记录数目" ,required=true ,dataType="int")
1174        public int rows;
1175    }
1176    /**
1177     * argClass-23<br>
1178     * wrap arguments for method {@link #matWearMask(MatWearMaskArgs)}
1179     */
1180    public static class MatWearMaskArgs{
1181        @ApiModelProperty(value ="图像矩阵类型" ,required=true ,dataType="MatType")
1182        public MatType matType;
1183        @ApiModelProperty(value ="图像矩阵" ,required=true ,dataType="byte[]")
1184        public byte[] matData;
1185        @ApiModelProperty(value ="图像宽度" ,required=true ,dataType="int")
1186        public int width;
1187        @ApiModelProperty(value ="图像高度" ,required=true ,dataType="int")
1188        public int height;
1189        @ApiModelProperty(value ="人脸位置信息" ,required=true ,dataType="CodeInfo")
1190        public CodeInfo faceInfo;
1191    }
1192    /**
1193     * argClass-25<br>
1194     * wrap arguments for method {@link #searchFaces(SearchFacesArgs)}
1195     */
1196    public static class SearchFacesArgs{
1197        @ApiModelProperty(value ="图片字节数组" ,required=true ,dataType="byte[]")
1198        public byte[] imgData;
1199        @ApiModelProperty(value ="人脸位置对象<br>\n"
1200+"            为{@code null}时,先做人脸检测再提取特征码<br>\n"
1201+"            不为{@code null}时,直接在指定的位置提取特征码<br>" ,required=true ,dataType="CodeInfo")
1202        public CodeInfo facePos;
1203        @ApiModelProperty(value ="相似度阀值" ,required=true ,dataType="double")
1204        public double similarty;
1205        @ApiModelProperty(value ="最多返回的记录数目" ,required=true ,dataType="int")
1206        public int rows;
1207    }
1208    /**
1209     * argClass-26<br>
1210     * wrap arguments for method {@link #searchFeatures(SearchFeaturesArgs)}
1211     */
1212    public static class SearchFeaturesArgs{
1213        @ApiModelProperty(value ="要搜索的特征码" ,required=true ,dataType="byte[]")
1214        public byte[] feature;
1215        @ApiModelProperty(value ="相似度阀值" ,required=true ,dataType="double")
1216        public double similarty;
1217        @ApiModelProperty(value ="最多返回的记录数目" ,required=true ,dataType="int")
1218        public int rows;
1219    }
1220    /**
1221     * argClass-27<br>
1222     * wrap arguments for method {@link #wearMask(WearMaskArgs)}
1223     */
1224    public static class WearMaskArgs{
1225        @ApiModelProperty(value ="图像数据(jpg,png...)字节数组,为{@code null}则抛出 {@link IllegalArgumentException}" ,required=true ,dataType="byte[]")
1226        public byte[] imgData;
1227        @ApiModelProperty(value ="可见光图像人脸信息" ,required=true ,dataType="CodeInfo")
1228        public CodeInfo faceInfo;
1229    }
1230    /**
1231     * 获取{@link FaceApi}实例的接口,
1232     * 用于应用层SPI方式提供{@link FaceApi}实例
1233     * @author guyadong
1234     *
1235     */
1236    public static interface InstanceSupplier{
1237        FaceApi instanceOfFaceApi();
1238    }
1239    /**
1240     * web响应数据接口
1241     * @author guyadong
1242     *
1243     */
1244    public static interface Response{
1245        /**
1246         * 接口方法调用成功
1247         * @param result 调用返回值
1248         */
1249        void onComplete(Object result);
1250        /**
1251         * 接口方法调用成功,调用方法返回类型为void
1252         */
1253        void onComplete();        
1254        /**
1255         * 接口方法调用抛出异常
1256         * @param e 异常
1257         */
1258        void onError(Exception e);
1259    }
1260    /**
1261     * 获取{@link Response}接口实例的工厂类接口
1262     * @author guyadong
1263     *
1264     */
1265    public static interface ResponseFactory{
1266        /**
1267         * @return 返回新的{@link Response}接口实例
1268         */
1269        Response newFaceApiResponse();
1270    }
1271    /**
1272     * {@link Response}默认实现
1273     * @author guyadong
1274     *
1275     */
1276    public static class DefaultResponse implements Response{
1277        private static boolean outStrackTrace = false;
1278        private boolean success;
1279        /** RPC调用的返回值 */
1280        private Object result;
1281        /** 异常信息 */
1282        private String errorMessage;
1283        /** 异常堆栈信息 */
1284        private String stackTrace;
1285        @Override
1286        public void onComplete(Object result) {
1287            this.success = true;
1288            this.result = result;
1289        }
1290        @Override
1291        public void onComplete() {
1292            onComplete(null);
1293        }
1294        @Override
1295        public void onError(Exception e) {
1296            success = false;
1297            errorMessage = e.getMessage();
1298            if(errorMessage == null){
1299                errorMessage = e.getClass().getSimpleName();
1300            }
1301            if(outStrackTrace){
1302                StringWriter writer = new StringWriter();
1303                e.printStackTrace(new PrintWriter(writer));
1304                stackTrace = writer.toString();
1305            }
1306        }
1307
1308        public boolean isSuccess() {
1309            return success;
1310        }
1311
1312        public void setSuccess(boolean success) {
1313            this.success = success;
1314        }
1315
1316        public Object getResult() {
1317            return result;
1318        }
1319
1320        public void setResult(Object result) {
1321            this.result = result;
1322        }
1323
1324        public String getErrorMessage() {
1325            return errorMessage;
1326        }
1327
1328        public void setErrorMessage(String errorMessage) {
1329            this.errorMessage = errorMessage;
1330        }
1331
1332        public String getStackTrace() {
1333            return stackTrace;
1334        }
1335
1336        public void setStackTrace(String stackTrace) {
1337            this.stackTrace = stackTrace;
1338        }
1339        
1340        @Override
1341        public String toString() {
1342            StringBuilder builder = new StringBuilder();
1343            builder.append("DefaultResponse [success=");
1344            builder.append(success);
1345            builder.append(", ");
1346            if (result != null) {
1347                builder.append("result=");
1348                builder.append(result);
1349                builder.append(", ");
1350            }
1351            if (errorMessage != null) {
1352                builder.append("errorMessage=");
1353                builder.append(errorMessage);
1354                builder.append(", ");
1355            }
1356            if (stackTrace != null) {
1357                builder.append("stackTrace=");
1358                builder.append(stackTrace);
1359            }
1360            builder.append("]");
1361            return builder.toString();
1362        }
1363        /**
1364         * 开启输出堆栈信息(默认为不开启)<br>
1365         * 开发时为了调试需要获取详细的异常堆栈信息可以开启
1366         * @param outStrackTrace 要设置的 outStrackTrace
1367         */
1368        public static void enableStrackTrace() {
1369            outStrackTrace = true;
1370        }
1371    }
1372    /**
1373     * {@link ResponseFactory}接口默认实现
1374     * @author guyadong
1375     *
1376     */
1377    public static class DefaultResponseFactory implements ResponseFactory{
1378
1379        @Override
1380        public Response newFaceApiResponse() {
1381            return new DefaultResponse();
1382        }
1383    }
1384    public static String DESCRIPTION = "人脸识别SDK核心接口<br>\n"
1385+" 此接口中mat前缀的方法图像数据参数为图像矩阵(要求图像宽高必须为偶数),\n"
1386+" 其他方法中所有byte[]类型的图像参数都指未解码的图像格式(如jpg,bmp,png...),<br>\n"
1387+" 目前支持的图像格式类型依赖于JDK的支持能力";
1388}