Как URI-кодировать изображение?
Я читаю документацию по Alchemy-API здесь:
http://www.alchemyapi.com/api/image-tagging/image.html
Они говорят, что изображение должно быть в кодировке URI... что именно это означает?
Означает ли это преобразование изображения в строку base64 с последующей передачей этого запроса?
Я пробовал это, но я получаю ошибку http 414 - слишком большой URI запроса.
Вот мой код, где сделан запрос:
@IBAction func analyzeImage(sender: UIButton) {
var imageData = UIImagePNGRepresentation(mainImage.image)
let base64ImageString = imageData.base64EncodedStringWithOptions(.allZeros)
let requestString = ENDPOINT+"?apikey="+API_KEY+"&image="+base64ImageString+"&outputMode=json"
let url = NSURL(string: requestString)
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
println(NSString(data: data, encoding: NSUTF8StringEncoding))
}
task.resume()
}
РЕДАКТИРОВАТЬ: я принял во внимание рекомендацию Dijkgraaf использовать POST-запрос вместо GET, чтобы обойти длину URI. Я использую библиотеку Alamofire, чтобы сделать это. Вот мой код:
@IBAction func analyzeImage(sender: UIButton) {
var imageData = UIImagePNGRepresentation(mainImage.image)
let base64ImageString = imageData.base64EncodedStringWithOptions(.allZeros)
let params = [
"apikey" : API_KEY,
"image" : base64ImageString,
"outputMode" : "json"]
var manager = Manager.sharedInstance
//Passing all the headers you want!
manager.session.configuration.HTTPAdditionalHeaders = [
"Content-Type": "application/x-www-form-urlencoded"
]
manager.request(.POST, ENDPOINT, parameters:params, encoding: .URL)
.response { (request, response, data, error) in
println(request)
println(response)
println(error)
}
}
Тем не менее, я получаю ошибку "не могу проанализировать: нисходящий поток", когда я пытаюсь это сделать.
Вот вывод консоли:
<NSMutableURLRequest: 0x1742040c0> { URL: http://access.alchemyapi.com/calls/image/ImageGetRankedImageKeywords }
Optional(<NSHTTPURLResponse: 0x17082c1e0> { URL: http://access.alchemyapi.com/calls/image/ImageGetRankedImageKeywords } { status code: 200, headers {
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "no-cache";
Connection = "keep-alive";
"Content-Length" = 326;
"Content-Type" = "application/json";
Date = "Mon, 08 Jun 2015 05:59:22 GMT";
Server = nginx;
"X-AlchemyAPI-CurrentVersion" = "12.15";
"X-AlchemyAPI-Error-Msg" = "cannot-analyze:downstream-issue";
"X-AlchemyAPI-Key" = [API KEY HIDDEN];
"X-AlchemyAPI-Params" = "sentiment=0&knowledgeGraph=0&detectedLanguage=unknown&submitLanguage=detect";
"X-AlchemyAPI-Status" = ERROR;
"X-AlchemyAPI-Total-Transactions" = 0;
} })
nil
Не уверен, что происходит не так, но в документации Alchemy действительно говорится, что для запросов POST заголовок "Content-Type" должен иметь значение "application/x-www-form-urlencoded", что, похоже, не происходит, несмотря ни на что. Я пытаюсь установить. Может ли это быть проблемой?
РЕДАКТИРОВАТЬ: Я попытался POSTing только необработанные данные изображения, снова, как Dijkgraaf предложил:
@IBAction func analyzeImage(sender: UIButton) {
var imageData = UIImagePNGRepresentation(mainImage.image)
//let base64ImageString = imageData.base64EncodedStringWithOptions(.allZeros)
var request = HTTPTask()
request.requestSerializer = HTTPRequestSerializer()
request.requestSerializer.headers["Content-Type"] = "application/x-www-form-urlencoded"
let params: Dictionary<String,AnyObject> = [
"apikey" : API_KEY,
"imagePostMode" : "raw",
"image" : imageData,
"outputMode" : "json"]
request.POST(ENDPOINT, parameters: params, completionHandler: {(response: HTTPResponse) in
println(response.headers)
})
}
но я все еще получаю ту же ошибку - не могу проанализировать ошибку выпуска.
2 ответа
При использовании imagePostMode raw необходимо отправить данные изображения в качестве тела запроса POST, а параметры должны быть включены в URL-адрес конечной точки (например, ENDPOINT="http://access.alchemyapi.com/calls/image/ImageGetRankedImageKeywords?apikey= api_key &outputMode= &imagePostMode JSON = сырой "). Я не работал со Swift, поэтому я не знаю лучшего способа сделать это, но он немного отличается от того, что вы могли ожидать.
Ниже код работает для меня.
let image = UIImage(named: "your-image.png")
getImageTag(image!)
func getImageTag(image:UIImage){
let apiKey = "xxx-xxx-xxx-xxx-xxx"
let url = "https://gateway-a.watsonplatform.net/calls/image/ImageGetRankedImageKeywords?imagePostMode=raw&outputMode=json&apikey=" + apiKey
let myURL = NSURL(string: url)!
let request = NSMutableURLRequest(URL: myURL)
request.HTTPMethod = "POST"
request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
let imageData = UIImagePNGRepresentation(image)
request.HTTPBody = imageData!
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
data, response, error in
// Your completion handler code here
if let error = error {
print("error: \(error)")
}
print(response)
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
}
task.resume()
}
Вы также можете протестировать Image Tagging Requst с помощью команды curl, как показано ниже.
curl --data-binary @your_image.png "https://gateway-a.watsonplatform.net/calls/image/ImageGetRankedImageKeywords?imagePostMode=raw&apikey=d3a529b15ac9ebe550a51006815xxxxxx"