Reputation: 61
I need to create a pipeline that would take an image from the dropbox, process it and upload it back (could be a different folder). The first two steps are easy, but there doesn't seem to be a way to upload the image to dropbox with the newer API V2. I have tried uploading a local image - read from computer and save it to dropbox, no success. The problem seems to be the format of the file, I get the following error:
expected request_binary as binary type
There are many examples for the text files and it works pretty well, while for the images the same solutions fail
import dropbox
from PIL import Image
dbx = dropbox.Dropbox('access_token') # Connecting to the account
metadata,file=dbx.files_download('/PATH_TO_IMAGE') # Getting the image from DropBox
im=Image.open(io.BytesIO(file.content)) # Getting the image to process
dbx.files_upload(im, '/PATH', mode=WriteMode('overwrite'))
Also tried:
dbx.files_upload_session_start(im)
Python3, dropbox SDK 9.4.0 actually I have tried putting the file in various formats, so instead of im there was also im.read(), np.array(im.getdata()).encode(), io.BytesIO(), local image from my computer but nothing works. And I do not understand how to transform the image data to 'request_binary as binary type'.
So what is needed, as I understand is a way to transform any file to 'request_binary'
TypeError: expected request_binary as binary type, got <class --SMTH ELSE-->
Upvotes: 1
Views: 1260
Reputation: 136359
I'd do this:
import dropbox
def load_image(filepath: str) -> bytes:
with open(filepath, "rb") as fp:
contents = fp.read()
return contents
contents = load_image("1.png")
dbx = dropbox.Dropbox("access_token") # Connecting to the account
dbx.files_upload(
contents, "/FOLDER/IMAGE.png", dropbox.files.WriteMode.add, mute=True
)
Upvotes: 1
Reputation: 61
Thanks to Greg I have found a solution, a bit easier than the one written in the example
import dropbox
from PIL import Image
import numpy as np
import io
def load_image(filepath: str) -> bytes:
image = Image.open(filepath) # any image
l = np.array(image.getdata())
# To transform an array into image using PIL:
channels = l.size // (image.height * image.width)
l = l.reshape(image.height, image.width, channels).astype(
"uint8"
) # unit8 is necessary to convert
im = Image.fromarray(l).convert("RGB")
# to transform the image into bytes:
with io.BytesIO() as output:
im.save(output, format="PNG")
contents = output.getvalue()
return contents
contents = load_image("1.png")
dbx = dropbox.Dropbox("access_token") # Connecting to the account
dbx.files_upload(
contents, "/FOLDER/IMAGE.png", dropbox.files.WriteMode.add, mute=True
)
Upvotes: 1