The code of the model is as follows
class Post(models.Model):
title = models.CharField(max_length=100)
file = models.FileField(null=True,blank=True,upload_to='Files')
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
I want to read the file (image or video).
Let's say its an image. I want to read this image in an array format.
I tried with the following code but i just get the file name and not a image matrix
img = Post.objects.all()[0].file
print(img)
OR
print(np.array(img))
Output is : car-1.jpg
Expected output : 2d Array
by default django store file or image path.. not a file
so you should get your file path + your url and use for example wget lib to get it after that you can use it
example:
import cv2, wget
image_url = 'server_url + link_from_query'
filename = wget.download(image_url)
np_image = cv2.imread(filename)
Related
I have django site where I am trying to create an excel file with an image in it.
The image is on a AWS: https://unord-tools-django-project-static.s3.eu-central-1.amazonaws.com/media/public/10e8f47bb84901d20ff435071577c58b_TFxmjcV.jpg
I am using: xlsxwriter==1.4.5
and trying to write it with:
worksheet_s.insert_image(5, thisColumn, str('https://unord-tools-django-project-static.s3.eu-central-1.amazonaws.com/media/public/'+image))
My model looks like this:
class Room(models.Model):
# Relationships
location = models.ForeignKey("asset_app.Locations", on_delete=models.SET_NULL, blank=True, null=True)
room_type = models.ForeignKey("asset_app.Room_type", on_delete=models.SET_NULL, blank=True, null=True)
# Fields
name = models.CharField(max_length=30)
image = models.ImageField(storage=PublicMediaStorage(), null=True, blank=True
)
The error I am getting is this:
worksheet_s.insert_image(5, thisColumn, str('https://unord-tools-django-project-static.s3.eu-central-1.amazonaws.com/media/public/'+image))
TypeError: can only concatenate str (not "ImageFieldFile") to str
XlsxWriter doesn't insert images directly from urls like that. You will need to read the data first. Something like this:
from io import BytesIO
from urllib.request import urlopen
import xlsxwriter
# Create the workbook and add a worksheet.
workbook = xlsxwriter.Workbook('image.xlsx')
worksheet = workbook.add_worksheet()
# Read an image from a remote url.
url = 'https://unord-tools-django-project-static.s3.eu-central-1.amazonaws.com/media/public/10e8f47bb84901d20ff435071577c58b_TFxmjcV.jpg'
image_data = BytesIO(urlopen(url).read())
# Write the byte stream image to a cell. Note, a dummy filename
# or description must be specified, or use a blank string.
worksheet.insert_image('B2', 'image name', {'image_data': image_data})
workbook.close()
Output:
I have a model with some fields:
class RankStructure(models.Model):
RankID = models.CharField(max_length=4)
SName = models.CharField(max_length=5)
Name = models.CharField(max_length=125)
LongName = models.CharField(max_length=512)
GENRE_CHOICES = (
('TOS', 'TOS'),
('TMP', 'TMP'),
('TNG', 'TNG'),
('DS9', 'DS9'),
('VOY', 'VOY'),
('KTM', 'KTM')
)
Genre = models.CharField(max_length=3, choices=GENRE_CHOICES)
image = models.FileField(upload_to='RANKS/'+<<GENRE>>+'/', blank=True)
In the last line is an image FileField. I want the folder to be associated with the Genre. So if the Genra is TOS, then the folder should be RANKS/TOS/image.jpg.
How do I set it so this happens?
Thanks.
You need a custom upload handler.
def image_upload_handler(instance, filename):
return 'RANKS/{genre}/{filename}'.format(
genre=instance.genre,
filename=filename
)
class RankStructure(models.Model):
image = models.ImageField(upload_to=image_upload_handler, blank=True)
Also I recommend using this for image fields: https://github.com/edoburu/django-any-imagefield
I am trying to create model for news. My model contains ImageField where i wont to store thumbnail:
class News(models.Model):
title = models.CharField(verbose_name=u'tytuł', max_length=40)
lead = models.TextField(verbose_name=u'zajawka', blank= False)
body = models.TextField(verbose_name=u'treść ogłosznia', blank=False)
author = models.ForeignKey(User)
active = models.BooleanField(verbose_name=u'aktywność ogłoszenia')
pub_date = models.DateTimeField(verbose_name=u'data publikacji')
slug = models.SlugField(unique=True)
lead_photo= models.ImageField(upload_to="lead_photo/")
objects= NewsManager()
I found on the other site code and i modified it to my needs:
def save(self, force_update=False, force_insert=False, thumb_size=(120,120)):
from PIL import Image
from cStringIO import StringIO
from django.core.files.uploadedfile import SimpleUploadedFile
image = Image.open(self.lead_photo)
if image.mode not in ('L', 'RGB'):
image = image.convert('RGB')
image.thumbnail(thumb_size, Image.ANTIALIAS)
# save the thumbnail to memory
temp_handle = StringIO()
image.save(temp_handle, 'JPEG')
temp_handle.seek(0) # rewind the file
# save to the thumbnail field
suf = SimpleUploadedFile(os.path.split(self.lead_photo.name)[-1],
temp_handle.read(),
content_type='image/jpeg')
self.lead_photo.save(suf.name+'.png', suf, save=False)
# save the image object
super(News, self).save(force_update, force_insert)
the problem is that i cant create thumbnail with different width and height proportion. When for instance a set thumb_size(240,320) i'll get the same proportion as in oryginal but picture is smaller. Thanks for advices.
Edit:
On PIL documentation i found very interesting sentence about that method:
"This method modifies the image to contain a thumbnail version of itself, no larger than the given size." So is there any option to make it exact that size?
You can try resize method.
And as a variant you can create new background image (doc):
newImage = Image.new(resized.mode, resized.size, "black")
and place your main image on it keeping aspect ratio resized by image.thumbnail(thumb_size, Image.ANTIALIAS).
You can use:
http://djangothumbnails.com/
from django.db import models
from thumbs import ImageWithThumbsField
class Person(models.Model):
photo = ImageWithThumbsField(upload_to='images', sizes=((125,125),(200,200)))
Do not forget intall pillow
pip install pillow
I am using Django 1.6. I have a model for uploading image files that looks like this.
class Image(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=255)
url = models.ImageField(upload_to=get_image_path,
null=True,
blank=True,
height_field = 'height',
width_field = 'width',
verbose_name='Image')
height = models.IntegerField(blank=True)
width = models.IntegerField(blank=True)
size = models.IntegerField(blank=True)
format = models.CharField(max_length=50)
caption = models.CharField(max_length=255)
def clean(self):
self.size = self.url.size
class Meta:
db_table = 'image'
As you can see, I am storing the size of the image when the clean() method is called. This works for what I want to do, but is this best practise? Is there a better way to automatically save the image's file size when saving?
The second part of my question is how can I get the content type as well?
Thanks,
Mark
Model.clean() should be used for validation - do not use it to update/save the data, but rather use it to correct any invalid data (or throw an exception/error message).
You may want to consider not even storing the size of the image in the database, given that you can access it from the ImageField - it eliminates the possibility of the data becoming inconsistent as it changes over time.
I believe this question/answer should address your second question.
For the first question
Check out the Python Imaging Library PIL on this thread.
from PIL import Image
im=Image.open(filepath)
im.size # (width,height) tuple
For the second question
HttpRequest.META, more specifically HttpRequest.META.get('CONTENT_TYPE')
from this thread
I'd like to implement a functionality in an app of mine, but I don't know how to go about it. What I want is this: I have a model class that uses imagekit to save its images, and I'd like to have the users being able to update the images easily for the vehicles without having to edit each respective vehicle record.
How they'll do this is that there will be a folder named originals and it'll contain folders for each vehicle in the format <stock_number>/PUBLIC If a user moves images into the PUBLIC folder for a vehicle, when the script is executed, it'll compare those images with the current ones and update them if those in the PUBLIC folder are newer. If the record has no images, then they will be added. Also, if the images have been deleted from the site_media directory, then their links should be deleted from the database.
How can I go about this in an efficient way? My models are as below:
class Photo(ImageModel):
name = models.CharField(max_length = 100)
original_image = models.ImageField(upload_to = 'photos')
num_views = models.PositiveIntegerField(editable = False, default=0)
position = models.ForeignKey(PhotoPosition)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
class IKOptions:
spec_module = 'vehicles.specs'
cache_dir = 'photos'
image_field = 'original_image'
save_count_as = 'num_views'
class Vehicle(models.Model):
objects = VehicleManager()
stock_number = models.CharField(max_length=6, blank=False, unique=True)
vin = models.CharField(max_length=17, blank=False)
....
images = generic.GenericRelation('Photo', blank=True, null=True)
Progress Update
I've tried out the code, and while it works, I'm missing something as I can get the image, but after that, they aren't transferred into the site_media/photos directory...am I suppossed to do this or imagekit will do this automatically? I'm a bit confused.
I'm saving the photos like so:
Photo.objects.create(content_object = vehicle, object_id = vehicle.id,
original_image = file)
My advice is running django script in a crontab job, lets say, 5 in 5 minutes.
The script would dive into the image folders and compare the images with the records.
A simplified example:
# Set up the Django Enviroment
from django.core.management import setup_environ
import settings
setup_environ(settings)
import os
from your_project.your_app.models import *
from datetime import datetime
vehicles_root = '/home/vehicles'
for stock_number in os.listdir(vehicles_root):
cur_path = vehicles_root+'/'+stock_number
if not os.path.isdir(cur_path):
continue # skip non dirs
for file in os.listdir(cur_path):
if not isfile(cur_path+'/'+file):
continue # skip non file
ext = file.split('.')[-1]
if ext.lower() not in ('png','gif','jpg',):
continue # skip non image
last_mod = os.stat(cur_path+'/'+file).st_mtime
v = Vehicle.objects.get(stock_number=stock_number)
if v.last_upd < datetime.fromtimestamp(last_mod):
# do your magic here, move image, etc.
v.last_upd = datetime.now()
v.save()