2015-06-08 15 views
7

Sto leggendo attraverso la documentazione alchimie-API qui:Come codificare un'immagine URI?

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

Si dice che l'immagine deve essere URI codificato ... che cosa significa esattamente?

Significa convertire l'immagine in una stringa base64 e quindi passarla alla richiesta?

Ho provato, ma ho ricevuto un errore http 414 - Richiedi URI troppo grande.

Ecco il mio codice in cui viene presentata la richiesta:

@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: ho preso in considerazione la raccomandazione del Dijkgraaf di utilizzare una richiesta POST invece di GET per aggirare la lunghezza URI. Sto usando la libreria Alamofire per fare questo. Qui è il mio codice:

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

Tuttavia, ho un "can not-analisi: downstream-problema" errore quando provo questo.

Ecco l'output della console:

<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 

Non so che cosa sta andando male, ma la documentazione Alchemy fa stato che richieste POST dovrebbe avere la "Content-Type" impostato su "application/x-www -form-urlencoded ", che non sembra accadere indipendentemente da ciò che cerco di impostare. Potrebbe essere questo il problema?

EDIT: Ho provato POSTing solo i dati di immagine grezzi, ancora una volta come Dijkgraaf suggerito:

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

} 

ma ho ancora lo stesso non-analizzare di nuovo l'errore problema a valle.

+2

"I documenti di immagine richiesti possono essere al massimo di 1 megabyte. Documenti di dimensioni maggiori generano una risposta all'errore" contenuto supera la dimensione ". qual è la dimensione dell'immagine che stai tentando di inviare? – Icaro

+0

Se l'immagine è di grandi dimensioni, probabilmente si desidera POSTARE un'immagine raw come menzionato in quella documentazione piuttosto che provare la codifica URI e usare GET con una querystring. Una lunghezza massima URI è di 2.083 caratteri è alcuni sistemi, e anche 255 caratteri sono alcuni altri. – Dijkgraaf

+0

@Icaro la mia immagine di prova è 156kb – snowflakekiller

risposta

5

Quando si utilizza imagePostMode raw, è necessario inviare i dati dell'immagine come corpo della richiesta POST e i parametri devono essere inclusi nell'URL endpoint (ad esempio ENDPOINT = "http://access.alchemyapi.com/ chiama/image/ImageGetRankedImageKeywords? apikey = API_KEY & outputMode = json & imagePostMode = raw "). Non ho lavorato con Swift, quindi non conosco il modo migliore per farlo, ma è leggermente diverso da quello che potresti aspettarti.

2

Il codice riportato di seguito funziona per me.

È inoltre possibile eseguire il test Requst di immagine con il comando di arricciatura come di seguito.

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