How to specify the "image" in the images/edits API

Hi,
I’m trying to use the openAI “images” API with old-fashioned Objective-C.
The API documents don’t say it, but it seems to require the content type to be multipart/form-data. Is this correct?
Assuming so, I’ve build my request header and body, but I’m getting an error returned from the API when I attempt to POST to the “v1/images/edits” endpoint. The error is “Missing image file in request. (Perhaps you specified ‘image’ in the wrong format?)”
The documentation for the API says that the image must be a valid PNG file, but I’m assuming it means a base64 encoded string representing the contents of a PNG file, right? (The option being you upload an image as a separate step and then reference the updated file by name.)
All of the samples I’ve seen hide the implementation of getting the raw base64 data, so some of these things have me a bit confused.
I’m going to paste the body of my request below. Note that for this sample, I used a 5x5 pixel image so that the body isn’t too long. Do you guys see anything obviously wrong with it?
Oh, in the header I’m just setting Content-Type, my boundary string and my API Key for authorization.
-Pete
Body as follows:
–Boundary-XYZZYString

Content-Disposition: form-data; name=“image”

iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAYAAACNMs+9AAAAAXNSR0IArs4c6QAAAGxlWElmTU0AKgAAAAgABAEaAAUAAAABAAAAPgEbAAUAAAABAAAARgEoAAMAAAABAAIAAIdpAAQAAAABAAAATgAAAAAAAACQAAAAAQAAAJAAAAABAAKgAgAEAAAAAQAAAAqgAwAEAAAAAQAAAAoAAAAAUVJR8wAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAABxpRE9UAAAAAgAAAAAAAAAFAAAAKAAAAAUAAAAFAAABDSp+3FoAAADZSURBVCgVAM0AMv8A2+f2/93q9//h7fn/4+/5/+Lu+f/h7vn/3un3/9zo9f/g7Pf/4e34/wDP3+z/0uHu/9jk8P/c6fb/2eXx/9Pe6v/R3ur/0+Ht/9Ti7P/U4ez/AMLX5v/E2Of/x9zr/6aqsP9uY2L/a1pY/4yEhP/G1eH/xtjm/8XY5f8Amqyy/6e6wv+Xpa7/LiQj/3lZTP+UbF7/rIh6/6y5xf+sxNb/qcDR/wCWlIz/nJ2M/0lDPP9JMCr/v4x6/6F3av+thXb/laV1/2l6aP9+i3T/AAAA//8qha+QAAAA1klEQVQBzQAy/wCDk2D/gpdb/2NyO/8/LiX/mWtT/6Z1ZP+ch2L/f6FD/36VVv9/k1H/AG2RQv+PnWD/0LeN/7OJdP+Wb1b/vZmE/4CBY/9zl0D/hKdP/4OoUf8AmIl4/01LVv+dgXn/4rSc/9OqlP/muqT/tJeL/2qKR/9+qEf/gKlK/wDfpIf/jm9f/x4kMf+li4D/78Or/+q8ov/KqJz/aYRN/3iiRP+Bp0//ALiEZf+keFr/QDU0/yEmNP/Ysp3/lH93/ycrPP9DXDv/cJpG/3ugU//j8RewkILXxAAAAABJRU5ErkJggg==

–Boundary-XYZZYString

Content-Disposition: form-data; name=“prompt”

convert to pencil sketch

–Boundary-XYZZYString

Content-Disposition: form-data; name=“n”

1

–Boundary-XYZZYString

Content-Disposition: form-data; name=“size”

256x256

–Boundary-XYZZYString

Content-Disposition: form-data; name=“response_format”

b64_json

–Boundary-XYZZYString

Content-Disposition: form-data; name=“user”

myTestAIIOSApp

–Boundary-XYZZYString–

I used Postman to get it to work. But, only by telling Postman that the image was coming from a file, not from data. At this point I can’t figure out how you’re supposed to specify the image data you’re sending along with the POST request.

Am I missing some key documentation?

Edit: A week later and I’m still trying to get this to work. I sniffed the successful call from Postman and it looks like the raw binary data is being sent to the endpoint. I specify “b64_json” as the return type, which although the docs don’t specify, I believe is “base 64 json”…
Now all I get is “image is a required property”. When I get this working, I’ll post my solution.

-Pete

Edit: I have it working.
The data representing the image definitely has to be binary. Standard rules for separating the parts of a multi-part request apply as usual.
What was causing me to stumble was that in Objective-C, the method on the NSData class, dataWithContentsOfFile, is, for some unknown reason, returning a byte stream that isn’t quite a valid PNG file. I did a hex dump and although the first 100 bytes are the same as the original file and the last 100 bytes are the same, there’s differences in the stream that I haven’t accounted for yet.

By creating a UIImage and then using the “PNGRepresentation” of that image that also return a PNG NSData block, the call works fine now.

Unfortunately a 1024x1024 PNG file is often over the five meg size limit, so I’m going to stick with 512 for now.

3 Likes