Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Uploading from camera library via xmlrpclib
-
I couldn't find anything else in the forums, but I'm trying to upload an image to a Wordpress site via xmlrpclib. I was able to do it with an image hosted online using this code:
def new_image(url, post_id = None): import urllib2 from re import findall raw = urllib2.urlopen(url) image = raw.read() content = {} content['bits'] = xmlrpclib.Binary(image) content['name'] = findall('[^\/]+?$',url)[0] content['type'] = 'image/jpeg' if post_id is not None: content['post_id'] = post_id img = server.wp.uploadFile(1,username,password,content) return img
(server, username and password are defined earlier)
I'm trying to do the same thing with an image chosen from my camera roll (I go through my company's Instagram feed and upload it for a weekly blog post, but sometimes I have a 4:3 version I want to use instead). To get
content['bits']
I'm using:import photos image = photos.pick_image(False, True, False) image[0].verify() content = {} content['bits'] = xmlrpclib.Binary(image[0].tostring())
This... works, in that an object is returned, but the image doesn't actually upload. See this example.
File and I/O stuff are what I hate most about coding, and I don't really understand all the components, so maybe (hopefully) there's something easy I'm missing.
-
See
Image.tostring()
Image.tostring(encoder, parameters)
Returns a string containing pixel data, using the given data encoding.
Note: The tostring method only fetches the raw pixel data. To save the image to a string in a standard file format, pass a StringIO object (or equivalent) to the save method.
tostring
is not returning the binary of an encoded image file, but more like the binary underlying the PIL image format. Use save instead with a StringIO object, then use getValue to get the binary.See https://omz-forums.appspot.com/pythonista/post/5520750224080896 for the basic approach, except you won't then convert to a ui.Image.
-
Thank you! But now I'm having trouble with
.save()
:with io.BytesIO() as bIO: image[0].save(bIO,'JPG') content['bits'] = bIO.getvalue()
The second line gives
KeyError: 'JPG'
. So I thought it might be interpreting that as an option and not format I added{'quality': 80}
and gotTypeError: save() takes at most 3 arguments (4 given)
So... It thinks there's an extra argument? To make sure
image[0]
was correct I did.show()
and it worked... -
Use 'jpeg ', not 'jpg'.
Actually, if you don't need to manipulate it at all, use the
raw_data=True
argument topick_image
, which returns the raw binary without having to use save, etc. -
Wonderful, thank you!
Using JPEG still didn't work, so I went the raw_data route, and it works perfectly. For posterity:
content = {} image = photos.pick_image(False, True, True ,True ) content['bits'] = xmlrpclib.Binary(image[0])