Django Models images + Crop
First create an Image model:
class Image(models.Model):
image = models.ImageField(upload_to="images")
class Meta:
verbose_name = _('Image')
verbose_name_plural = _('Images')
Then we add a Crop model to carry crop related data for each image:
class Crop(models.Model):
image = models.OneToOneField(Image, related_name='crop', on_delete=models.CASCADE)
x = models.IntegerField()
y = models.IntegerField()
width = models.IntegerField()
height = models.IntegerField()
class Meta:
verbose_name = _('Crop')
verbose_name_plural = _('Crops')
The x, y and width and height fields will define the image metadata for our crop.
Like in HTML, these are canvas coordinates where the upper left starts at coordinates (0, 0)
x and y indicates our starting point of the crop relative to the image from the top left x , y axis.
The width indicates distance we go from the x to the right.
And the height indicates distance we go from the y to the bottom.
I recommend a seperate API view to handle the images. The following solution includes the ability to crop and make thumbnails using easy_thumbnails:
class GetImageAPIView(APIView):
def get(self, request, imageid):
image = get_object_or_404(Image, pk=int(imageid))
params = request.query_params
width = int(params.get('width'))
height = int(params.get('height'))
to_crop = True if params.get('crop') == 'yes' else False
try:
crop = image.crop
except:
crop = None
fimage = image.image
if to_crop and crop:
x = crop.x
y = crop.y
x2 = x + crop.width
y2 = y + crop.height
x_width = crop.width
y_height = crop.height
crop_box = '%s,%s,%s,%s' % (x,y,x2,y2)
thumbnailer = get_thumbnailer(fimage)
cropped_image = thumbnailer.get_thumbnail({
'size': (x_width, y_height),
'box': crop_box,
'detail': True,
'upscale': True
})
fimage = cropped_image
th = get_thumbnail(fimage, '%sx%s' % (width, height), upscale=True, padding=True, quality=99, padding_color="black")
url = request.build_absolute_uri(th.url)
return response.Response({'url': url}, status=status.HTTP_200_OK)
Finally, to actually save the crop information for an image, this all depends on the frontend implementation. Once it's saved you can then serve it in an HTML image tag or whatever.
Comments
Post a Comment