Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to URI-Encode image?

I am reading through the alchemy-API documentation here:

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

They say that the image must be URI-encoded... what exactly does that mean?

Does it mean converting the image to a base64 string and then passing that to the request?

I've tried that but I receive a http 414 error - Request URI too large.

Here is my code where the request is made:

    @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: I took into account Dijkgraaf's recommendation to use a POST request instead of GET to work around the URI length. I am using the Alamofire library to do this. Here is my 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)
    }
}

However, i get a "cannot-analyze:downstream-issue" error when I try this.

Here is the console output:

<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

Not sure what is going wrong, but the Alchemy documentation does state that POST requests should have the "Content-Type" header set to "application/x-www-form-urlencoded", which doesn't seem to be happening no matter what I try to set. Could this be the issue?

EDIT: I tried POSTing just the raw image data, again as Dijkgraaf suggested:

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

}

but I still get the same cannot-analyze downstream issue error again.

like image 666
snowflakekiller Avatar asked Jun 08 '15 03:06

snowflakekiller


People also ask

What is IMG URI?

Online image to Data URI conversion tool Data URI is a method for embedding small images directly in your HTML or CSS code using base64 encoding without the need for additional image files.

How do I convert a URL to an image?

Free tool to convert Data URI to image (png) file. Data URI is an Uniform Resource Identifier scheme that provides a way to include data in-line in webpages. You need to copy & paste the Data URI as input and you can save the output image file. Note : For reverse conversion, use Image to DataURI Converter.

How do I convert an image to base64?

Convert Images to Base64 Just select your JPG, PNG, GIF, Webp, or BMP picture or drag & drop it in the form below, press the Convert to Base64 button, and you'll get a base-64 string of the image. Press a button – get base64. No ads, nonsense, or garbage. Drag and drop your image here!


1 Answers

When using imagePostMode raw, you need to send the image data as the body of the POST request, and the parameters should be included in the endpoint URL (for example ENDPOINT="http://access.alchemyapi.com/calls/image/ImageGetRankedImageKeywords?apikey=API_KEY&outputMode=json&imagePostMode=raw"). I haven't worked with Swift so I don't know the best way to do this, but it's a little different than what you might expect.

like image 108
Zach Walchuk Avatar answered Oct 23 '22 11:10

Zach Walchuk