2015-06-08 10 views
7

Ich lese über die Alchemie-API-Dokumentation hier:Wie URI-Encode-Bild?

http://www.alchemyapi.com/api/image-tagging/image.html

Sie sagen, dass das Bild URI-codiert werden muss ... was genau bedeutet das?

Bedeutet es, das Bild auf ein Base64-String konvertieren und dann die Anfrage an die vorbei?

Ich habe das versucht, aber ich erhalten Sie einen http 414 Fehler - Anfrage zu groß URI.

Hier ist mein Code, in dem der Antrag gestellt wird:

@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() 
} 

EDIT: Ich berücksichtigte Dijkgraaf Empfehlung eine POST-Anforderung zu verwenden anstelle von GET um die URI Länge zu arbeiten. Ich benutze die Alamofire-Bibliothek, um dies zu tun. Hier ist mein Code:

@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) 
    } 
} 

aber ich erhalte eine „nicht-Analyse: Downstream-Problem“ Fehler, wenn ich das versuchen. Hier

ist die Konsolenausgabe:

<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 

nicht sicher, was falsch läuft, aber die Alchemy Dokumentation Zustand ist, dass POST-Anfragen sollten den "Content-Type" Header gesetzt haben „application/x-www -form-urlencodiert ", das scheint nicht zu passieren, egal was ich versuche zu setzen. Könnte das das Problem sein?

EDIT: Ich habe gerade versucht, die rohen Bilddaten-Posting, wieder als Dijkgraaf vorgeschlagen:

@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) 
    }) 

} 

aber ich habe immer noch das gleiche wieder Downstream Problem Fehler nicht analysieren kann.

+2

"Gewünscht Bilddokumente können maximal 1 Megabyte sein. Größere Dokumente in einer führen werden "Content-übersteigt-size-limit" Fehlerreaktion." Wie groß ist das Bild, das Sie senden möchten? – Icaro

+0

Wenn das Bild groß ist, möchten Sie wahrscheinlich ein RAW-Bild POSTIEREN, wie in dieser Dokumentation erwähnt, anstatt die URI-Codierung zu versuchen und GET mit einer Abfragezeichenfolge zu verwenden. Die maximale Länge eines URI beträgt 2.083 Zeichen bei einigen Systemen und sogar 255 Zeichen bei einigen anderen. – Dijkgraaf

+0

@Icaro mein Testbild ist 156kb – snowflakekiller

Antwort

5

Wenn Sie imagePostMode root verwenden, müssen Sie die Bilddaten als Hauptteil der POST-Anforderung senden, und die Parameter sollten in der Endpunkt-URL enthalten sein (z. B. ENDPOINT = "http://access.alchemyapi.com/ Aufrufe/image/ImageGetRankedImageKeywords? apikey = API_KEY & outputMode = json & imagePostMode = roh "). Ich habe nicht mit Swift gearbeitet, also weiß ich nicht, wie das am besten funktioniert, aber es ist ein bisschen anders als das, was Sie erwarten könnten.

2

Unten Code funktioniert für mich.

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() 
} 

Sie können auch wie unten Bild Tagging requst von curl Befehl testen.

curl --data-binary @your_image.png "https://gateway-a.watsonplatform.net/calls/image/ImageGetRankedImageKeywords?imagePostMode=raw&apikey=d3a529b15ac9ebe550a51006815xxxxxx"