/* * Copyright 2016 Baidu, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * specific language governing permissions and limitations under the License. */ package com.baidubce.services.ocr; import java.io.UnsupportedEncodingException; import java.net.URI; import java.util.ArrayList; import java.util.List; import com.baidubce.AbstractBceClient; import com.baidubce.BceClientConfiguration; import com.baidubce.BceClientException; import com.baidubce.http.Headers; import com.baidubce.http.HttpMethodName; import com.baidubce.http.handler.BceErrorResponseHandler; import com.baidubce.http.handler.BceJsonResponseHandler; import com.baidubce.http.handler.BceMetadataResponseHandler; import com.baidubce.http.handler.HttpResponseHandler; import com.baidubce.internal.InternalRequest; import com.baidubce.internal.RestartableInputStream; import com.baidubce.services.ocr.model.BankcardRecognitionRequest; import com.baidubce.services.ocr.model.BankcardRecognitionResponse; import com.baidubce.services.ocr.model.FormAbstractBceRequest; import com.baidubce.services.ocr.model.GeneralRecognitionRequest; import com.baidubce.services.ocr.model.GeneralRecognitionResponse; import com.baidubce.services.ocr.model.IdcardRecognitionRequest; import com.baidubce.services.ocr.model.IdcardRecognitionResponse; import com.baidubce.util.HttpUtils; import static com.baidubce.util.Validate.checkStringNotEmpty; import static com.google.common.base.Preconditions.checkNotNull; /** * Created by lvsiyuan on 16/11/18. */ public class OcrClient extends AbstractBceClient { private static final String VERSION = "api/v1"; private static final String PATH_OCR = "ocr"; private static final String PARA_GENERAL = "general"; private static final String PARA_BANK = "bankcard"; private static final String PARA_ID = "idcard"; private static final String FORM_CONTENT_TYPE = "application/x-www-form-urlencoded"; /** * Responsible for handling httpResponses from all Ocr service calls. */ private static final HttpResponseHandler[] responseHandlers = new HttpResponseHandler[] { new BceMetadataResponseHandler(), new BceErrorResponseHandler(), new BceJsonResponseHandler() }; /** * Constructs a new client using the client configuration. * * @param ocrConfig The client configuration options controlling how this client connects to Ocr services * (e.g. proxy settings, retry counts, etc). */ public OcrClient(BceClientConfiguration ocrConfig) { // enable HTTP Async manner for PUT method super(ocrConfig, responseHandlers, true); } /** * Gets the bankcard recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param image The image data which needs to be base64 * @return The bankcard recognition properties of the image resource */ public BankcardRecognitionResponse bankcardRecognition(String image) { BankcardRecognitionRequest request = new BankcardRecognitionRequest().withImage(image); return bankcardRecognition(request); } /** * Gets the bankcard recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param request The request wrapper object containing all options. * @return The bankcard recognition properties of the image resource */ public BankcardRecognitionResponse bankcardRecognition(BankcardRecognitionRequest request) { checkNotNull(request, "request should not be null."); checkStringNotEmpty(request.getImage(), "Image should not be null or empty!"); InternalRequest internalRequest = createRequest(HttpMethodName.POST, request, PARA_BANK); return invokeHttpClient(internalRequest, BankcardRecognitionResponse.class); } /** * Gets the idcard recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param image The image data which needs to be base64 * @param side The side of idcard image. (front/back) * @return The idcard recognition properties of the image resource */ public IdcardRecognitionResponse idcardRecognition(String image, String side) { IdcardRecognitionRequest request = new IdcardRecognitionRequest().withImage(image).withSide(side); return idcardRecognition(request); } /** * Gets the idcard recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param image The image data which needs to be base64 * @param side The side of idcard image. (front/back) * @param direction Decide if the image has been rotated (true/false) * @return The idcard recognition properties of the image resource */ public IdcardRecognitionResponse idcardRecognition(String image, String side, Boolean direction) { IdcardRecognitionRequest request = new IdcardRecognitionRequest().withImage(image) .withSide(side).withDirection(direction); return idcardRecognition(request); } /** * Gets the idcard recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param request The request wrapper object containing all options. * @return The idcard recognition properties of the image resource */ public IdcardRecognitionResponse idcardRecognition(IdcardRecognitionRequest request) { checkNotNull(request, "request should not be null."); checkStringNotEmpty(request.getImage(), "Image should not be null or empty!"); InternalRequest internalRequest = createRequest(HttpMethodName.POST, request, PARA_ID); return invokeHttpClient(internalRequest, IdcardRecognitionResponse.class); } /** * Gets the general recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param image The image data which needs to be base64 * @return The general recognition properties of the image resource */ public GeneralRecognitionResponse generalRecognition(String image) { GeneralRecognitionRequest request = new GeneralRecognitionRequest().withImage(image); return generalRecognition(request); } /** * Gets the general recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param image The image data which needs to be base64 * @param granularity Decide if recognize single character (big/small) * @param mask Represent the gray/white/black shade image area (base64 data) * @param langType Language type, detail to be CHN_ENG (ENG/POR/FRE/GER/ITA/SPA/RUS/JAP) * @param direction Decide if the image has been rotated (true/false) * @return The general recognition properties of the image resource */ public GeneralRecognitionResponse generalRecognition(String image, String granularity, String mask, String langType, Boolean direction) { GeneralRecognitionRequest request = new GeneralRecognitionRequest().withImage(image) .withGranularity(granularity).withMask(mask).withLangType(langType).withDirection(direction); return generalRecognition(request); } /** * Gets the general recognition properties of specific image resource. * * <p> * The caller <i>must</i> authenticate with a valid BCE Access Key / Private Key pair. * * @param request The request wrapper object containing all options. * @return The general recognition properties of the image resource */ public GeneralRecognitionResponse generalRecognition(GeneralRecognitionRequest request) { checkNotNull(request, "request should not be null."); checkStringNotEmpty(request.getImage(), "Image should not be null or empty!"); InternalRequest internalRequest = createRequest(HttpMethodName.POST, request, PARA_GENERAL); return invokeHttpClient(internalRequest, GeneralRecognitionResponse.class); } /** * Creates and initializes a new request object for the specified resource. This method is responsible for * determining HTTP method, URI path, credentials and request body for POST method. * <p> * <b>Note: </b> The Query parameters in URL should be specified by caller method. * </p> * * @param httpMethod The HTTP method to use when sending the request. * @param request The original request, as created by the user. * @param pathVariables The optional variables in URI path. * @return A new request object, populated with endpoint, resource path, ready for callers to populate any * additional headers or parameters, and execute. */ private InternalRequest createRequest( HttpMethodName httpMethod, FormAbstractBceRequest request, String...pathVariables) { // Build URL paths List<String> pathComponents = new ArrayList<String>(); pathComponents.add(VERSION); pathComponents.add(PATH_OCR); // Append resourceKeys,pathVariables, // For example:/resourcekey1/resourcekey2/../pathVariable1/pathVariable2 if (pathVariables != null) { for (String pathVariable : pathVariables) { pathComponents.add(pathVariable); } } URI uri = HttpUtils.appendUri(getEndpoint(), pathComponents.toArray(new String[pathComponents.size()])); // Get a InternalRequest instance and set headers InternalRequest internalRequest = new InternalRequest(httpMethod, uri); internalRequest.setCredentials(request.getRequestCredentials()); if (httpMethod == HttpMethodName.POST || httpMethod == HttpMethodName.PUT) { fillRequestPayload(internalRequest, request); } return internalRequest; } private InternalRequest fillRequestPayload(InternalRequest internalRequest, FormAbstractBceRequest request) { String strFormParameters = request.toFormString(); byte[] requestJson = null; try { requestJson = strFormParameters.getBytes(DEFAULT_ENCODING); } catch (UnsupportedEncodingException e) { throw new BceClientException("Unsupported encode.", e); } internalRequest.addHeader(Headers.CONTENT_LENGTH, String.valueOf(requestJson.length)); internalRequest.addHeader(Headers.CONTENT_TYPE, FORM_CONTENT_TYPE); internalRequest.setContent(RestartableInputStream.wrap(requestJson)); return internalRequest; } }