Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BDE
nk20
Commits
82924c99
Commit
82924c99
authored
Sep 06, 2020
by
erdnaxe
🦋
Browse files
Add animated profile picture support
parent
72c004cb
Pipeline
#8674
passed with stages
in 10 minutes and 57 seconds
Changes
2
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
apps/member/forms.py
View file @
82924c99
...
...
@@ -3,7 +3,7 @@
import
io
from
PIL
import
Image
from
PIL
import
Image
,
ImageSequence
from
django
import
forms
from
django.conf
import
settings
from
django.contrib.auth.forms
import
AuthenticationForm
...
...
@@ -82,13 +82,19 @@ class ImageForm(forms.Form):
height
=
forms
.
FloatField
(
widget
=
forms
.
HiddenInput
())
def
clean
(
self
):
"""Load image and crop"""
"""
Load image and crop
In the future, when Pillow will support APNG we will be able to
simplify this code to save only PNG/APNG.
"""
cleaned_data
=
super
().
clean
()
# Image size is limited by Django DATA_UPLOAD_MAX_MEMORY_SIZE
image
=
cleaned_data
.
get
(
'image'
)
if
image
:
# Let Pillow detect and load image
# If it is an animation, then there will be multiple frames
try
:
im
=
Image
.
open
(
image
)
except
OSError
:
...
...
@@ -96,20 +102,30 @@ class ImageForm(forms.Form):
# but Pil is unable to load it
raise
forms
.
ValidationError
(
_
(
'This image cannot be loaded.'
))
# Crop
imag
e
# Crop
each fram
e
x
=
cleaned_data
.
get
(
'x'
,
0
)
y
=
cleaned_data
.
get
(
'y'
,
0
)
w
=
cleaned_data
.
get
(
'width'
,
200
)
h
=
cleaned_data
.
get
(
'height'
,
200
)
im
=
im
.
crop
((
x
,
y
,
x
+
w
,
y
+
h
))
im
=
im
.
resize
(
(
settings
.
PIC_WIDTH
,
settings
.
PIC_RATIO
*
settings
.
PIC_WIDTH
),
Image
.
ANTIALIAS
,
)
frames
=
[]
for
frame
in
ImageSequence
.
Iterator
(
im
):
frame
=
frame
.
crop
((
x
,
y
,
x
+
w
,
y
+
h
))
frame
=
frame
.
resize
(
(
settings
.
PIC_WIDTH
,
settings
.
PIC_RATIO
*
settings
.
PIC_WIDTH
),
Image
.
ANTIALIAS
,
)
frames
.
append
(
frame
)
# Save
om
=
frames
.
pop
(
0
)
# Get first frame
om
.
info
=
im
.
info
# Copy metadata
image
.
file
=
io
.
BytesIO
()
im
.
save
(
image
.
file
,
"PNG"
)
if
len
(
frames
)
>
1
:
# Save as GIF
om
.
save
(
image
.
file
,
"GIF"
,
save_all
=
True
,
append_images
=
list
(
frames
),
loop
=
0
)
else
:
# Save as PNG
om
.
save
(
image
.
file
,
"PNG"
)
return
cleaned_data
...
...
apps/member/views.py
View file @
82924c99
...
...
@@ -271,9 +271,17 @@ class PictureUpdateView(ProtectQuerysetMixin, LoginRequiredMixin, FormMixin, Det
def
form_valid
(
self
,
form
):
"""Save image to note"""
image_field
=
form
.
cleaned_data
[
'image'
]
image_field
.
name
=
"{}_pic.png"
.
format
(
self
.
object
.
note
.
pk
)
self
.
object
.
note
.
display_image
=
image_field
image
=
form
.
cleaned_data
[
'image'
]
# Rename as a PNG or GIF
extension
=
image
.
name
.
split
(
"."
)[
-
1
]
if
extension
==
"gif"
:
image
.
name
=
"{}_pic.gif"
.
format
(
self
.
object
.
note
.
pk
)
else
:
image
.
name
=
"{}_pic.png"
.
format
(
self
.
object
.
note
.
pk
)
# Save
self
.
object
.
note
.
display_image
=
image
self
.
object
.
note
.
save
()
return
super
().
form_valid
(
form
)
...
...
erdnaxe
🦋
@erdnaxe
mentioned in issue
#5 (closed)
·
Sep 06, 2020
mentioned in issue
#5 (closed)
mentioned in issue #5
Toggle commit list
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment