Gitlab CSE Unil

Commit 1125b211 authored by Julien Furrer's avatar Julien Furrer
Browse files

Changed thumbnail management

Functions for Thumbnail creation and borders are 
now in adim_app.utils

Thumbnail creation and border are called at view
level from adim_app (no more in models)

Thumbnail size in settings, no more hardcoded
parent 004342d8
.DS_Store .DS_Store
*.pyc *.pyc
*.swp *.swp
*.bak
.idea .idea
screen_session_cmd screen_session_cmd
......
...@@ -8,8 +8,9 @@ from django.contrib.contenttypes import generic ...@@ -8,8 +8,9 @@ from django.contrib.contenttypes import generic
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.utils import timezone from django.utils import timezone
# from PIL import Image
from sorl.thumbnail import ImageField, get_thumbnail # from sorl.thumbnail import ImageField, get_thumbnail
from eav.models import BaseEntity, BaseSchema, BaseAttribute, BaseChoice from eav.models import BaseEntity, BaseSchema, BaseAttribute, BaseChoice
...@@ -21,6 +22,7 @@ RANDOM_NODE = random.randrange(0, 1 << 48L) | 0x010000000000L ...@@ -21,6 +22,7 @@ RANDOM_NODE = random.randrange(0, 1 << 48L) | 0x010000000000L
# Destination path for uploaded images, relative to MEDIA_ROOT # Destination path for uploaded images, relative to MEDIA_ROOT
AO_IMAGES_PATH = 'ao_images' AO_IMAGES_PATH = 'ao_images'
class AOType(models.Model): class AOType(models.Model):
name = models.CharField(max_length=128) name = models.CharField(max_length=128)
title = models.CharField(max_length=512, blank=True, default="") title = models.CharField(max_length=512, blank=True, default="")
...@@ -84,12 +86,12 @@ class AnObj(BaseEntity): ...@@ -84,12 +86,12 @@ class AnObj(BaseEntity):
filename = self.uuid + file_ext filename = self.uuid + file_ext
return os.path.join( return os.path.join(
AO_IMAGES_PATH, AO_IMAGES_PATH,
self.owner.username,
now.strftime("%Y"), now.strftime("%Y"),
now.strftime("%m"), now.strftime("%m"),
now.strftime("%d"),
filename filename
) )
image = ImageField(upload_to=get_image_path, verbose_name=_("image"), blank=True, null=True) image = models.ImageField(upload_to=get_image_path, verbose_name=_("image"), blank=True, null=True)
_thumb_url = models.CharField(max_length=512, blank=True, null=True) _thumb_url = models.CharField(max_length=512, blank=True, null=True)
...@@ -114,6 +116,9 @@ class AnObj(BaseEntity): ...@@ -114,6 +116,9 @@ class AnObj(BaseEntity):
self._set_uuid(no_save=True) self._set_uuid(no_save=True)
super(AnObj, self).save(*args, **kwargs) super(AnObj, self).save(*args, **kwargs)
# if not self._thumb_url:
# self._thumb_url = self._create_thumbnail()
# self.save()
def _set_uuid(self, no_save=False): def _set_uuid(self, no_save=False):
if not self.uuid: if not self.uuid:
...@@ -123,11 +128,29 @@ class AnObj(BaseEntity): ...@@ -123,11 +128,29 @@ class AnObj(BaseEntity):
if not no_save: if not no_save:
self.save() self.save()
# def _create_thumbnail(self):
# if not self.image:
# return
#
# th_path = os.path.splitext(self.image.path)[0] + "__.png"
# if os.path.exists(th_path):
# return th_path
#
# im = Image.open(self.image.path)
# im.thumbnail(settings.ADIM_THUMB_SIZE)
# im.save(th_path)
# return th_path
@property @property
def thumb_url(self): def thumb_url(self):
if not self._thumb_url: if not self._thumb_url:
im = get_thumbnail(self.image.name, '150x150', quality=80) # th_size = (150, 150)
self._thumb_url = im.url # th_path = os.path.splitext(self.image.path)[0] + "__.png"
# im = Image.open(self.image.path)
# im.thumbnail(th_size)
# im.save(th_path)
# im = get_thumbnail(self.image.name, '150x150', quality=80)
self._thumb_url = self._create_thumbnail()
self.save() self.save()
return self._thumb_url return self._thumb_url
......
...@@ -151,8 +151,8 @@ define([ ...@@ -151,8 +151,8 @@ define([
fullySelectedAnnot = $.map(selectedAnnot, function(e){ return e.fullySelected ? e : null}); fullySelectedAnnot = $.map(selectedAnnot, function(e){ return e.fullySelected ? e : null});
paper.project.deselectAll(); paper.project.deselectAll();
if (options && options.thumbnail) { if (options && options.thumbnailSize) {
paper.view.zoom = options.thumbnail / Math.max(ts.width, ts.height); paper.view.zoom = options.thumbnailSize / Math.max(ts.width, ts.height);
view.resize(ts.width * paper.view.zoom, ts.height * paper.view.zoom); view.resize(ts.width * paper.view.zoom, ts.height * paper.view.zoom);
} else { } else {
paper.view.zoom = 1; paper.view.zoom = 1;
...@@ -168,7 +168,7 @@ define([ ...@@ -168,7 +168,7 @@ define([
// return; // return;
// } // }
df.resolve({blob: blob}); df.resolve({blob: blob});
if (!options || !options.thumbnail) { if (!options || !options.thumbnailSize) {
saveAs(blob, baseFileName + ".png"); saveAs(blob, baseFileName + ".png");
} }
}); });
...@@ -192,7 +192,7 @@ define([ ...@@ -192,7 +192,7 @@ define([
function _getThumbnail(options) { function _getThumbnail(options) {
options.thumbnail = 150; options.thumbnailSize = parseInt(config.thumbnailSize, 10) || 150;
return _exportPng(null, options); return _exportPng(null, options);
} }
......
...@@ -120,7 +120,6 @@ define([ ...@@ -120,7 +120,6 @@ define([
.on('mouseup', function(){ isMouseDown = false; }); .on('mouseup', function(){ isMouseDown = false; });
function _sendThumbnail() { function _sendThumbnail() {
// console.log("_sendThumbnail");
var postpone = isMouseDown || textToolInput.is(":visible"); var postpone = isMouseDown || textToolInput.is(":visible");
if (postpone) { if (postpone) {
sendThumbnail(); sendThumbnail();
...@@ -131,17 +130,14 @@ define([ ...@@ -131,17 +130,14 @@ define([
callback: ui.adjustCanvasToImage callback: ui.adjustCanvasToImage
}) })
.done(function(params){ .done(function(params){
io.saveThumbnail(config.annotable.id, params.blob) io.saveThumbnail(config.annotable.id, params.blob)
.done(function(data){ .done(function(data){
ui.setState('thumbSaved'); ui.setState('thumbSaved');
// ui.updateCurrentThumbnail(data); // ui.updateCurrentThumbnail(data);
// console.log("thumbnail exported: " + data);
}) })
}); });
} }
return function() { return function() {
// console.log("sendThumbnail");
if (!textToolInput || textToolInput.length === 0) if (!textToolInput || textToolInput.length === 0)
textToolInput = $("#"+CANVAS_EL_ID).siblings("input.text-tool-input"); textToolInput = $("#"+CANVAS_EL_ID).siblings("input.text-tool-input");
......
{% extends "adim_app/base_annotation.html" %} {% extends "adim_app/base_annotation.html" %}
{% load static i18n %} {% load static i18n %}
{% block page_head %}{% endblock %}
{% block navbar_content %} {% block navbar_content %}
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li><a href="#" class="adim-image-name"> <li><a href="#" class="adim-image-name">
...@@ -71,7 +69,8 @@ window.ADIM_CONFIG = { ...@@ -71,7 +69,8 @@ window.ADIM_CONFIG = {
initial_tool: 'select' initial_tool: 'select'
}, },
uploadMaxFileSize: {{ UPLOAD_MAX_FILESIZE }} * Math.pow(2, 20) thumbnailSize: parseInt("{{ THUMB_SIZE.0 }}", 10),
uploadMaxFileSize: parseInt('{{ UPLOAD_MAX_FILESIZE }}',10) * Math.pow(2, 20)
}; };
</script> </script>
{% endblock %} {% endblock %}
......
# coding=utf-8
from __future__ import unicode_literals
from .images import add_border as add_image_border
from .images import create_thumbnail as create_image_thumbnail
\ No newline at end of file
# coding=utf-8
from __future__ import unicode_literals
import os
from PIL import Image
from django.conf import settings
def add_border(img, save=False):
if type(img) == str or type(img) == unicode:
try:
thumb_image = Image.open(img)
thumb_path = img
except IOError:
# TODO: log some error
return
elif Image.isImageType(img):
thumb_image = img
thumb_path = img.filename
else:
raise TypeError()
brd_w = 1
overlay_image = Image.new(thumb_image.mode, thumb_image.size, color=(0, 0, 0))
result_image = Image.blend(thumb_image, overlay_image, alpha=0.33)
result_image.paste(
thumb_image.crop(
(brd_w, brd_w) + tuple(a - brd_w for a in thumb_image.size)
),
box=(brd_w, brd_w)
)
if save:
result_image.save(thumb_path)
return result_image
def create_thumbnail(image_path):
th_path = os.path.splitext(image_path)[0] + "__.png"
if os.path.exists(th_path):
return th_path
im = Image.open(image_path)
im.thumbnail(settings.ADIM_THUMB_SIZE)
im = add_border(im, save=False)
im.save(th_path, 'PNG')
return th_path
\ No newline at end of file
# coding=utf-8
from __future__ import unicode_literals
import json import json
import os import os
from django.conf import settings from django.conf import settings
...@@ -12,6 +15,8 @@ from PIL import Image ...@@ -12,6 +15,8 @@ from PIL import Image
from adim.models import AnObj from adim.models import AnObj
from .forms import UploadImageFileForm from .forms import UploadImageFileForm
from sendfile import sendfile from sendfile import sendfile
from .utils import add_image_border, create_image_thumbnail
def home(request): def home(request):
""" """
...@@ -87,6 +92,7 @@ def anobj_thumb(request, anobj_uuid): ...@@ -87,6 +92,7 @@ def anobj_thumb(request, anobj_uuid):
@login_required @login_required
@cache_control(public=True, max_age=1)
def send_anobj_thumb(request, anobj_uuid): def send_anobj_thumb(request, anobj_uuid):
try: try:
anobj = _get_anobj(request, anobj_uuid=anobj_uuid) anobj = _get_anobj(request, anobj_uuid=anobj_uuid)
...@@ -150,12 +156,15 @@ def upload_file(request, anobj_uuid=None): ...@@ -150,12 +156,15 @@ def upload_file(request, anobj_uuid=None):
anobj = _get_anobj(request, anobj_uuid=anobj_uuid) anobj = _get_anobj(request, anobj_uuid=anobj_uuid)
anobj.image = image_file anobj.image = image_file
anobj.save() anobj.save()
except Http404: except Http404:
anobj = AnObj.objects.create( anobj = AnObj.objects.create(
owner=request.user, owner=request.user,
name=os.path.splitext(image_file.name)[0], name=os.path.splitext(image_file.name)[0],
image=image_file image=image_file
) )
create_image_thumbnail(anobj.image.path)
response_data['next'] = reverse('adim.app:annotate', kwargs={'anobj_uuid': anobj.uuid}) response_data['next'] = reverse('adim.app:annotate', kwargs={'anobj_uuid': anobj.uuid})
# Needed when using iFrame transport # Needed when using iFrame transport
...@@ -214,7 +223,7 @@ def upload_anobj_thumb(request, anobj_uuid=None): ...@@ -214,7 +223,7 @@ def upload_anobj_thumb(request, anobj_uuid=None):
thumb_name = os.path.splitext(anobj.image.name)[0] + '__.png' thumb_name = os.path.splitext(anobj.image.name)[0] + '__.png'
thumb_path = os.path.join(settings.MEDIA_ROOT, thumb_name) thumb_path = os.path.join(settings.MEDIA_ROOT, thumb_name)
thumb_url = reverse('adim.app:ao_thumb', kwargs={'anobj_uuid': anobj.uuid}) # thumb_url = reverse('adim.app:ao_thumb', kwargs={'anobj_uuid': anobj.uuid})
thumb_file = request.FILES['file'] thumb_file = request.FILES['file']
response_data = _validate_uploaded_file(thumb_file) response_data = _validate_uploaded_file(thumb_file)
...@@ -225,28 +234,59 @@ def upload_anobj_thumb(request, anobj_uuid=None): ...@@ -225,28 +234,59 @@ def upload_anobj_thumb(request, anobj_uuid=None):
for chunk in thumb_file.chunks(): for chunk in thumb_file.chunks():
destination.write(chunk) destination.write(chunk)
add_borders(thumb_path) add_image_border(thumb_path, save=True)
# add_borders(thumb_path)
if anobj.thumb_url != thumb_url:
anobj.thumb_url = thumb_url # if anobj.thumb_url != thumb_url:
anobj.save() # anobj.thumb_url = thumb_url
# anobj.save()
return HttpResponse(anobj.thumb_url, content_type="text/plain")
return HttpResponse()
# return HttpResponse(anobj.thumb_url, content_type="text/plain")
def add_borders(thumb_path):
brd_w = 1
# def add_borders(thumb_path):
thumb_image = Image.open(thumb_path) # brd_w = 1
overlay_image = Image.new(thumb_image.mode, thumb_image.size, color=(0, 0, 0)) #
result_image = Image.blend(thumb_image, overlay_image, alpha=0.33) # thumb_image = Image.open(thumb_path)
result_image.paste( # overlay_image = Image.new(thumb_image.mode, thumb_image.size, color=(0, 0, 0))
thumb_image.crop( # result_image = Image.blend(thumb_image, overlay_image, alpha=0.33)
(brd_w, brd_w) + tuple(a - brd_w for a in thumb_image.size) # result_image.paste(
), # thumb_image.crop(
box=(brd_w, brd_w) # (brd_w, brd_w) + tuple(a - brd_w for a in thumb_image.size)
) # ),
result_image.save(thumb_path) # box=(brd_w, brd_w)
# )
# result_image.save(thumb_path)
# def add_borders2(img, save=False):
# if type(img) == str or type(img) == unicode:
# try:
# thumb_image = Image.open(img)
# thumb_path = img
# except IOError:
# # TODO: log some error
# return
# elif Image.isImageType(img):
# thumb_image = img
# thumb_path = img.filename
# else:
# raise TypeError()
#
# brd_w = 1
#
# overlay_image = Image.new(thumb_image.mode, thumb_image.size, color=(0, 0, 0))
# result_image = Image.blend(thumb_image, overlay_image, alpha=0.33)
# result_image.paste(
# thumb_image.crop(
# (brd_w, brd_w) + tuple(a - brd_w for a in thumb_image.size)
# ),
# box=(brd_w, brd_w)
# )
# if save:
# result_image.save(thumb_path)
# return result_image
def _handle_uploaded_file(image_file, destination): def _handle_uploaded_file(image_file, destination):
......
...@@ -9,6 +9,7 @@ def default(request): ...@@ -9,6 +9,7 @@ def default(request):
context_extras.update({ context_extras.update({
'UPLOAD_MAX_FILESIZE': settings.ADIM_UPLOAD_MAX_FILESIZE, 'UPLOAD_MAX_FILESIZE': settings.ADIM_UPLOAD_MAX_FILESIZE,
'THUMB_SIZE': settings.ADIM_THUMB_SIZE,
'JS_MIN': '' if settings.ADIM_DEBUG_JS else '.min' 'JS_MIN': '' if settings.ADIM_DEBUG_JS else '.min'
}) })
......
# Max filesize in Mb # Max filesize in Mb
ADIM_UPLOAD_MAX_FILESIZE = 50 ADIM_UPLOAD_MAX_FILESIZE = 50
# Size of the Thumbnail
ADIM_THUMB_SIZE = (150, 150)
# If True load the non-minified version of adim js
ADIM_DEBUG_JS = False ADIM_DEBUG_JS = False
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment