0

[enter image description here][1]I have been trying to consume azure cognitive 'face detect' service. While passing the image as a url I am able to get a positive response from service, but when passing after converting the image in bytes the service does throw error: { "code": "InvalidImageSize", "message": "Image size is too small." } I did made sure (in debug mode) byte size after conversion was 1194Kb, which is well under limit (1Kb to 6Mb). Though I am not sure what I am doing wrong :|

I did tried converting image to bytes in multiple ways but all went in vain.

My ultimate aim is: instead of reading image from local, I need to accept a base64 representation of image and call this face detect service.

Any help would be much appreciated, thank you.

String photo = "C:\\dev\\check.jpeg";
        try {
            byte[] readAllBytes = Files.readAllBytes(Paths.get(photo));
            ByteArrayEntity reqEntity = new ByteArrayEntity(readAllBytes, ContentType.APPLICATION_OCTET_STREAM);

            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            headers.set("Ocp-Apim-Subscription-Key", "xxxxxxxxxxxx");

            Map<String, String> params = new HashMap<>();
            params.put("returnFaceId", "true");
            params.put("recognitionModel", "recognition_02");
            params.put("detectionModel", "detection_02");

            ResponseEntity<List<DetectFaceRes>> exchange = restTemplateFaceApiService.exchange(getUri(DETECT_FACE.getMapping()), HttpMethod.POST, new HttpEntity<>(reqEntity, headers), new ParameterizedTypeReference<List<DetectFaceRes>>(){}, params);
            if(responseHasTargetFace(exchange)) {
                return exchange.getBody();
            }
            log.error("some error");
            throw someExpception()
        }

Error:
{
    "code": "InvalidImageSize",
    "message": "Image size is too small."
}


  [1]: https://i.stack.imgur.com/JJH8U.jpg
Prashant
  • 1
  • 3
  • Is this with Spring? If so, it'll be instructive to include that declaration – cthrash Sep 27 '19 at 16:29
  • @cthrash: Yes, it's with Spring. Tag added. Thanks! – Prashant Sep 27 '19 at 17:16
  • I meant the bit of code that implements `exchange`. I'm not a Spring expert but my suspicion is that you get a chunked transfer, which the service does not support. You should be able to disable chunking by adding a `Content-Length` header, IIUC. Take a look at https://stackoverflow.com/questions/50110138/spring-boot-disable-transfer-coding-from-response-header – cthrash Sep 27 '19 at 20:44
  • Thanks @cthrash for your comment, I did tried switching off chunking earlier but was getting the same response. Even passed content size in request header but :( – Prashant Sep 28 '19 at 05:18
  • I directly use byte array instead of ByteArrayEntity from apache, and get a success. Check my answer to see if it helps. Thanks. – Jack Jia Oct 02 '19 at 03:52

2 Answers2

0

To simplify the test, I just read the response as a string. I download your picture and use it in my code.

I get a success with the following code:

    public static void TestRestTemplateExchange() {
        RestTemplate rt = new RestTemplate();

        String photo = "C:\\Users\\v-linjji\\Pictures\\test.jpg";
        byte[] readAllBytes = null;
        try {
            readAllBytes = Files.readAllBytes(Paths.get(photo));
        } catch (IOException e) {
            e.printStackTrace();
        }

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.set("Ocp-Apim-Subscription-Key","1fb1*********eb8b");

        Map<String, String> params = new HashMap<>();
        params.put("returnFaceId", "true");
        params.put("recognitionModel", "recognition_02");
        params.put("detectionModel", "detection_02");

        String url = "https://southeastasia.api.cognitive.microsoft.com/face/v1.0/detect";
        ResponseEntity<String> responseEntity = null;
        String responseBody = null;
        try {
            responseEntity = rt.exchange(url,HttpMethod.POST, new HttpEntity<>(readAllBytes, headers), String.class,params);
            responseBody = responseEntity.getBody();
            System.out.println(responseBody);
        }catch (HttpClientErrorException e){
            System.out.println(e.getResponseBodyAsString());
        }
    }

Response:

[{"faceId":"75c3c9dc-be49-4c16-a54c-a1710062967b","faceRectangle":{"top":570,"left":360,"width":444,"height":444}}]
Jack Jia
  • 5,268
  • 1
  • 12
  • 14
0

I was getting the same error because I was opening the photo before the recognition. So I removed the open and the code worked. I was programming in Python.