iT邦幫忙

0

Google API Error "Bad image data" (已解決卻不明白原因)

  • 分享至 

  • xImage

今天我設計了一個程式 主要功能是能夠讀取File夾內的image

並且將其傳給google的API

再將其分析資料寫入txt檔

不過在上傳的途中並沒有得到正確的回覆

在我的exception 中被抓到

package AI_Machine_Learning.google_api;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import com.google.cloud.vision.v1.AnnotateImageRequest;
import com.google.cloud.vision.v1.AnnotateImageResponse;
import com.google.cloud.vision.v1.BatchAnnotateImagesResponse;
import com.google.cloud.vision.v1.EntityAnnotation;
import com.google.cloud.vision.v1.Feature;
import com.google.cloud.vision.v1.Image;
import com.google.cloud.vision.v1.ImageAnnotatorClient;
import com.google.cloud.vision.v1.Feature.Type;
import com.google.protobuf.ByteString;

public abstract class ReadTheImg {
	
	public void analysisPicture(String inputDir, String outputDir)  throws Exception {
		
		  ImageAnnotatorClient vision = ImageAnnotatorClient.create(); // Google client obj
		  List<AnnotateImageRequest> requests = new ArrayList<AnnotateImageRequest>();
		  // Google Client Request //
		  
		  File input = new File(inputDir);
		  String[] inputFileNames = input.list();      // input.list() = file's name
		  for(String inputName: inputFileNames) {
			  String fileName = inputDir + "/" + inputName;
			  
			  Path path = Paths.get(fileName);         // Read the path by the fileName 
			  byte[] data = Files.readAllBytes(path);  // Read the data by the path
			  ByteString imgBytes = ByteString.copyFrom(data); // Create ByteString object
			  
			  Image img = Image.newBuilder().setContent(imgBytes).build();
			  Feature feat = Feature.newBuilder().setType(Type.LABEL_DETECTION).build(); // label like description and score
			  
			  AnnotateImageRequest request = AnnotateImageRequest.newBuilder()  // Create request (for run)
					  .addFeatures(feat)
					  .setImage(img)
					  .build();
			  requests.add(request);  // Throw to ArrayList at row 32
		  }
		  
		  List<List<String[]>> dataList = new ArrayList<List<String[]>>();
		  BatchAnnotateImagesResponse response = vision.batchAnnotateImages(requests); // Call google API
		  List<AnnotateImageResponse> responses = response.getResponsesList();         // Throw response to response list
		  
		  for(AnnotateImageResponse res : responses) {
			  if(res.hasError()) {
				  System.out.println(res.getError().getMessage());
				  return;
			  }
			  List<String[]> datas = new ArrayList<String[]>();
			  
			  for(EntityAnnotation annotation : res.getLabelAnnotationsList()) {
				  String[] data = new String[2];
				  data[0] = annotation.getDescription();
				  data[1] = String.valueOf(annotation.getScore());
				  
				  datas.add(data);
			  }
			  dataList.add(datas);
		  }
		  writeData(outputDir, inputFileNames, dataList);
  	   
	}
	public abstract void writeData(String outDir, String[] inputFileNames, List<List<String[]>> dataList);
  }

	

程式碼中的這個部分 res.hasError 為 1
所以return後沒有執行

  for(AnnotateImageResponse res : responses) {
			  if(res.hasError()) {
				  System.out.println(res.getError().getMessage());
				  return;
			  }
			  List<String[]> datas = new ArrayList<String[]>();
			  
			  for(EntityAnnotation annotation : res.getLabelAnnotationsList()) {
				  String[] data = new String[2];
				  data[0] = annotation.getDescription();
				  data[1] = String.valueOf(annotation.getScore());
				  
				  datas.add(data);
			  }
			  dataList.add(datas);
		  }
		  writeData(outputDir, inputFileNames, dataList);
  	   
	}

原因為 Bad image data

不過我確認過圖片內容是沒有問題的

這個技術有點新 還懇請大大們指教


之後將

    if(res.hasError()) {			System.out.println(res.getError().getMessage());
				  return;
			  }

註解後就能夠執行 而且跑出正確結果 不過我仍然不明白

圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
Darwin Watterson
iT邦好手 1 級 ‧ 2018-11-14 09:54:30

因為 if(res.hasError()) 條件成立後做了 return動作 離開 analysisPicture 這個 function ! 後續的程式碼都不會做
可試試把 return 拿掉,應該還是能正確執行!

不過既然是在 for迴圈中判斷,應該用 break 或 continue 比較洽當!
也可以把 return 替換成 break 或 continue,應該還是能正確執行!

補充另一個可能的issue:
如果上方建議會出錯,也有可能是res.hasError()本身會拋錯!
此時可以把後續的程式碼先丟進try-catchcatchfinally中測試!
如果能順利運作表示你也要處理hasError()的拋錯問題!

動手試試以上建議你就會懂了!

===========================================================

如果是要問什麼原因造成 Bad Image data,可先檢查圖片是否被 Google 支援!
官方所支援圖片:Supported Images
檢查看看是不是圖片檔案格式像素或者檔案大小的問題!

然後學著去找API文件吧!以後遇到類似問題 google 一下就解決了!

ps. 如果是依據上方連結檢查圖片是沒問題的,那你遇到的問題可能也是開發者
當時沒考慮到的!只能期待開發者有來IT幫並看到你的問題!因為這種標示v1、v2...
的套件,有些錯誤你可能只能期待下一個版本能幫你此理掉此問題!或者你也可以針對
你使用此一套件是要解決怎樣的問題重新發問,也許版上有其他邦友解過相同的問題願
意回覆,你有機會學到其他的解法!

a000114 iT邦新手 5 級 ‧ 2018-11-14 19:29:05 檢舉

我知道res.hasErroe會拋錯,所以我不能執行下面的敘述

可是我不明白為什麼今天Google API會拋錯

我想知道為何會丟出exception

我要發表回答

立即登入回答