I'm trying to send an image through my Android application to Django, where it will make the analysis of that image (with python code). I'm sending the image in Base64, but when I receive it, the format gets all messed up. How can I send the image correctly, and is this the right format?
Have you tried using this?
link
combined with a code like that:
class UploadedImageSerializer(serializers.ModelSerializer):
"""
Serializer for the UPloadedImage Model
Provides the pk, image, thumbnail, title and description
"""
class Meta:
model = UploadedImage
fields = ('pk', 'image', 'thumbnail', 'title', 'description', )
read_only_fields = ('thumbnail',)
Related
Hi I am new to Django and I am currently using it to create a web service. I am connecting android to django and would like to upload and image from android to django imagefield. I am using serializer to save the data in json. this code works on normal web, however, I am not sure what image file format to send over to the server and how to configure the server's file handling
This is what my views.py looks like :
`def post(self, request):
serializer = PhotoSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)`
Hi you should try to create a serializers class for save the image from that way:
class ModelNameSaveSerializers(serializers.ModelSerializer):
image_field = serializers.ImageField()
class Meta:
model = ModelName
fields = ('id'.. antoher_fields, 'image_field')
I'm trying to show an image on a html page, I received the image from the android client (base64), now I want to make it appears on a html page.
This is the code of the reception, I don't know what is the next step.
socket.on("image", function (image) { //réception d'une image
console.log(" image réçu : " +image)
//use fs.writeFile
image = image.replace(/^data:image\/png;base64,/, "");
require("fs").writeFile("out.png", image, 'base64',function(err) {
console.log(err);
});
});
As you said this is server side, What you can do is, emit the base64 code as it is to the web client. And on the web client, use JavaScript to replace the src attribute of the image div where you are planning to display the image.
Client side sample code below:
Socket.on("image", function(){
document.getElementById('img').setAttribute( 'src', 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==' );
}
This shold work, in the place of the dummy base64 that I used, you can use yours.
I have to upload an image from Android device to a web app written in Python and Django. For storing images, I have made use of easy thumbnails.
What I have done so far is convert the image to base64 string to and post it to server. Well this is working perfectly, also if I write the base64 string to png image file it goes smoothly.
Now, I want to save it to the database as far as I know, easy thumbnails save the actual file to some location on server within the app file structure, and saves a link to same in database.
I am not understanding, how do I save the base64 string I receive in POST to my database.
My Model:
class Register(models.Model):
image = ThumbnailerImageField(upload_to=filename, blank=True, null=True, max_length=2048)
def filename(inst, fname):
f = sha256(fname + str(datetime.now())).hexdigest()
return '/'.join([inst.__class__.__name__, f])
The image is not stored in the db. It is stored to disk. Only a reference to the file is stored in the db.
def Article(models.model):
image = models.ImageField(...)
Somewhere you create a new object:
from django.core.files.base import ContentFile
obj = Article()
data = base64.b64decode(encoded)
# You might want to sanitise `data` here...
# Maybe check if PIL can read the `data`?
obj.image.save('some_file_name.ext', ContentFile(data))
obj.save()
I am building an app-engine endpoint api that takes picture from a user (android app) and saves it to blobstore programmatically. Then I save the blob_key in my datastore. The code goes like this:
First I received the image through my #endpoint.method as a messages.BytesField:
image_data = messages.BytesField(1, required=True)
Then I save to the blobstore like this:
from google.appengine.api import files
def save_image(data):
# Create the file
file_name = files.blobstore.create(mime_type='image/png')
# Open the file and write to it
with files.open(file_name, 'a') as f:
f.write('data')
# Finalize the file. Do this before attempting to read it.
files.finalize(file_name)
# Get the file's blob key
blob_key = files.blobstore.get_blob_key(file_name)
return blob_key # which is then saved to datastore
Now I want to serve the image back. I don't see how to fit the following code into my endpoints api:
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
In the end I imagine a serving procedure like this:
in #endpoints.method:
get blob_key from datastore
obtain image with blob_key
add image to StuffResponseMessage
send StuffResponseMessage to front-end (android app)
My approach is because I want to protect the privacy of my users. Any thoughts on how to do this well? My code snippets are generally from the google developer tutorial.
EDIT:
I don't see how I would pass the blob_key from the datastore to the following method to retrieve the image:
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
What's inside resource, anyway?
I believe resource is the BlobKey object of what you want to serve, as a string, retreived from url path. If you look at the source of google.appengine.ext.blobstore.BlobInfo the get method uses a function __normalize_and_convert_keys that takes an argument of BlobKey object OR string.
If the blob is an image, maybe it's best to send the serving url instead to your Android app, in StuffResponseMessage maybe in your case. From google's Serving a Blob doc:
If you are serving images, a more efficient and potentially less-expensive method is to use get_serving_url using the App Engine Images API rather than send_blob. The get_serving_url function lets you serve the image directly, without having to go through your App Engine instances.
So after you save the image, take the returned blob_key (as per your method save_image(data) above) to make a serving url, then in your Android app get the image from the returned url. That of course means exposing the image url without privacy protection.
If you want to do it with protection, use BlobReader class to read the blob with file like interface. You can't use the method/class from Serving a Blob example because you do it in a remote.Service subclass rather than a handler.
How should my controller action look like when receiving image from an Android or iPhone?
My image model is the following:
class Image < ActiveRecord::Base
attr_accessible :user_id, :file_path
belongs_to :user
mount_uploader :file_path, FileUploader
end
The current controller:
class ImagesController < ApplicationController
protect_from_forgery :except => [:upload]
def upload
user = User.find(params[:user_id])
# I have no idea what else I have to do...
end
end
I'm in doubt how Carrierwave magically save the files to the server and what should I do in the controller to receive that Post.
file_path is now a field in your model. This means when you pass that field into your controller when creating a new model, it will automatically pick that up and save it.
Your multipart file data should be send as params[:image][:file_path] when creating a new Model, assuming the create method in your controller is being passed params[:image].