Converting base64 to .jpg file, then saving in Django database - python

def upload_image(request):
if request.is_ajax and request.POST:
image = request.POST.get('image')
image_name = request.POST.get('image_name')
imgdata = base64.b64decode(image + '==')
extension = image_name.split('.')[1].lower()
image_name = '{}_{}_profile_image.{}'.format(request.user.first_name, request.user.last_name, extension)
with open(image_name, "wb") as image_file:
image_file.write(imgdata)
upload = ProfileImage(
file=image_file,
user = request.user.username
)
upload.save()
data = {
}
return JsonResponse(data)
I am trying to crop images in Django using Croppie.js. The images are then uploaded to an S3 bucket.
I have the cropping working and it is returning the image cropped as a base64 string. I decoded it and write it to a new image file so that it could be then saved in the database.
When it it gets to upload.save() I am getting the error.
AttributeError: '_io.BufferedWriter' object has no attribute '_committed'
I'm not sure what the problem is. This is my first time working with base64 images and im not sure if im missing something when i'm converting back to a file or what is going on.

I was able to find a solution by using ContentFile
from django.core.files.base import ContentFile
def upload_image(request):
if request.is_ajax and request.POST:
image = request.POST.get('image')
image_name = request.POST.get('image_name')
extension = image_name.split('.')[1].lower()
image_name = '{}_{}_profile_image.{}'.format(request.user.first_name, request.user.last_name, extension)
imgStr = image.split(';base64')
data = ContentFile(base64.b64decode(imgStr[1]), name=image_name)
upload = Upload(
file=data,
user = request.user.username
)
# Saves upload to S3 bucket
upload.save()
data = {
}
return JsonResponse(data)
It converts the base64 string to a file that is readable by django.

Related

Python Flask app posting an image and using cv2.imread function

I made a small python app for face recognition and now I am converting it into a flask application.
#app.route('/save', methods=['POST'])
def save_image():
if request.method == 'POST':
if 'imageFile' not in request.files:
return {"detail": "No file found"}, 400
image = request.files['imageFile']
imageFileName = secure_filename(image.filename)
image.save('./images/' + imageFileName)
image = cv2.imread('./images/' + imageFileName)
image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
face_encoding = face_recognition.face_encodings(image)[0]
np.savetxt('./encodings/' + request.form['indexNumber'] + '.csv', face_encoding, delimiter=',')
return 'saving image'
In the above code I have saved the image posted to the server and read it again using cv2.imread and have later used it to create the face encoding. What I want is to do this without saving the image in the server. Is there a way to directly read the image posted and use like above?

How to get image from the web and save it to a imageField using the url

I'm trying to get a image from the web and save it to the imageField using the images url.
The below code spits out a error ('JpegImageFile' object has no attribute '_committed').
from PIL import Image
import urllib.request
import io
if form.is_valid():
instance = form.save(commit=False)
URL = 'http://www.image.jpg'
with urllib.request.urlopen(URL) as url:
file = io.BytesIO(url.read())
img = Image.open(file)
instance.image = img
instance.image has to be of type django.core.files.images.ImageFile I am testing my models with this code. Maybe it points you to the correct direction :
# This gets me a temp Image for testing. In your case it would be a real file
def get_test_image_file(tmpdir=None):
file = tempfile.NamedTemporaryFile(suffix='.png', dir=tmpdir)
return ImageFile(file, name=file.name)
and the for the model test I do :
def test_addimage_create(self):
adimage = AdImage.objects.create(advertiser=self.advertiser,
picture=get_test_image_file(tmpdir=MEDIA_ROOT))
self.assertIsInstance(adimage, AdImage)
so in your case instead of instance.image = img. img has to be an Object of Type ImageFile which then can be assigned to the form.instance. Btw. you should assign the values to the instance before save()

Save Base64 String into Django ImageField

Im doing an application that uses Django in server-side.
Im trying to do that:
import uuid
from base64 import b64decode
from django.core.files.base import ContentFile
#staticmethod
def add_photo(user, person, image_base64):
photo = DatabasePersonPhoto()
photo.user = user
photo.person = person
image_data = b64decode(image_base64)
image_name = str(uuid.uuid4())+".jpg"
photo.image = ContentFile(image_data, image_name)
photo.save()
return photo
This is my Base64 String:
data:image/jpeg;base64,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
The image file is generated, but I cant open it like an image.
I think this will be a best approach tried it and tested in django 1.10. based on this SO answer: https://stackoverflow.com/a/28036805/6143656
I made a function for decoded base64 file.
def decode_base64_file(data):
def get_file_extension(file_name, decoded_file):
import imghdr
extension = imghdr.what(file_name, decoded_file)
extension = "jpg" if extension == "jpeg" else extension
return extension
from django.core.files.base import ContentFile
import base64
import six
import uuid
# Check if this is a base64 string
if isinstance(data, six.string_types):
# Check if the base64 string is in the "data:" format
if 'data:' in data and ';base64,' in data:
# Break out the header from the base64 content
header, data = data.split(';base64,')
# Try to decode the file. Return validation error if it fails.
try:
decoded_file = base64.b64decode(data)
except TypeError:
TypeError('invalid_image')
# Generate file name:
file_name = str(uuid.uuid4())[:12] # 12 characters are more than enough.
# Get the file name extension:
file_extension = get_file_extension(file_name, decoded_file)
complete_file_name = "%s.%s" % (file_name, file_extension, )
return ContentFile(decoded_file, name=complete_file_name)
Then you can call the function
import decode_base64_file
p = Post(content='My Picture', image=decode_based64_file(your_base64_file))
p.save()
I found the solution.
I need to use only the parte without data:image/jpeg;base64,
In Python, we can do it with something like this:
image_base64 = image_base64.split('base64,', 1 )
fh = open("imageToSave.png", "wb")
fh.write(imgData.decode('base64'))
fh.close()
Edit (klaus-d): The code above gives an example, how to store an image file from BASE64 encoded data. It opens a file imageToSave.png in binary mode for writing, then decodes the base64 image data and write the result to the file. At the end it closes the file descriptor.

Python PIL Save Image to Different "Folder" on Amazon S3

I need to save my avatar to the "avatar" folder inside my Amazon S3 bucket.
Bucket
-Static
--Misc
-Media
--Originals
--Avatars
Currently, when I create the avatar, it is saved to the Originals "folder". My goal is to save it to the Avatars "folder".
Here is my code for creating and saving the avatar
def create_avatar(self):
import os
from PIL import Image
from django.core.files.storage import default_storage as storage
if not self.filename:
return ""
file_path = self.filename.name
filename_base, filename_ext = os.path.splitext(file_path)
thumb_file_path = "%s_thumb.jpg" % filename_base
if storage.exists(thumb_file_path):
return "exists"
try:
# resize the original image and return url path of the thumbnail
f = storage.open(file_path, 'r')
image = Image.open(f)
width, height = image.size
size = 128, 128
image.thumbnail(size, Image.ANTIALIAS)
f_thumb = storage.open(thumb_file_path, "w")
image.save(f_thumb, "JPEG", quality=90)
f_thumb.close()
return "success"
except:
return "error"
I was able to save the avatar to the desired "folder" by renaming the file path with a simple python replace() function.
This did the trick if anyone else ever need to "move" a file within the S3 bucket
thumb_file_path = thumb_file_path.replace('originals/', 'avatar/')

Convert uploaded file to GIF and then POST to web service

I need to take an uploaded JPG from request.FILES, convert it to a GIF thumbnail and then POST it to a 3rd party web service.
import StringIO
import Image
import requests
img_file = request.FILES['files[]'] if request.FILES else None
#create the thumbnail
import StringIO
thumb_buffer = StringIO.StringIO()
im = Image.open(img_file)
im.thumbnail(settings.THUMBNAIL_SIZE)
im.save(thumb_buffer, "GIF")
thumb_buffer.seek(0)
thumb_contents = thumb_buffer.getvalue()
thumb_buffer.close()
#send file via POST request
thumb_upload_dict = {
'upload_file': (filename + '.gif', thumb_contents)}
print thumb_upload_dict
thumb_payload = {
'func': 'upload_file',
'base_id': new_asset.base_id,
'type': 'GIF',
'username': 'remote_admin',
'password': 'we1398fj'
}
r = requests.post(url, params=thumb_payload, files=thumb_upload_dict)
Unfortunately this doesn't work. When I try to view the image I get The image “http://theurl.com/gif_filename.gif” cannot be displayed because it contains errors.
I should note that if I just POST img_file without converting it, it works fine. I'm guessing the problem has to do with thumb_contents but I'm not totally sure.

Categories