在Django中使用PIL添加图片水印
我有一个应用程序,主要是处理图片。用户可以上传图片,如果管理员批准了这些图片,它们就会出现在网页上。不过,这些图片对那些不在特定计划中的用户是不可见的。用户需要购买一个计划,才能下载这些图片。但我们知道,用户可以通过右键点击来保存图片。所以,为了保护这些图片,我决定给它们加上水印,使用PIL这个库。
我在这里找到了一篇教程 http://www.pythoncentral.io/watermark-images-python-2x/。但是因为我对Python和Django非常陌生,所以不太确定怎么在我的Django应用中实现这个教程。这个教程是针对单张图片的,但我有很多图片。我想知道怎么一次性给所有图片加水印。我在views.py中使用了这个定义来展示网页上的图片。
def showimage(request,template = 'base.html',page_template = 'photo/showimage.html'):
photo_list = Photo.objects.all()
context = {}
context.update({
'photo_list': photo_list,
'page_template': page_template,
})
if request.is_ajax():
template = page_template
return render_to_response(template,context,context_instance=RequestContext(request))
这是我的showimage.html,我在这里渲染了我的图片……
{% extends 'base.html'%}
{%block title%}{%endblock%}
{%block content%}
{% load endless %}
<div class="container" >
<div class="row mt" style="padding-top:0px; margin-top:10px;">
<ul class="grid effect-2" id="grid">
{% paginate 40 photo_list %}
{% for photo in photo_list%}
{% if photo.approved%}
<li><a href = "{% url 'download_image' photo.id %}">
<img src={{photo.photo.url}} alt = 'sample photo' /></a>
</li>
{%endif%}
{% endfor %}
</ul>
</div><!-- row -->
</div><!-- container -->
<p>{%show_more%}</p>
{%endblock%}
其实不一定要只用上面给的链接,你也可以用自己的代码来修改我上面给出的视图。
2 个回答
免责声明:我是这个水印教程的作者。
补充信息:关于网站输出,这里有一些修改:
import os, sys, StringIO ## change line 2 ##
def add_watermark(in_file, angle=23, opacity=0.25): ## change line 6 ##
out_file = StringIO.StringIO() ## insert after line 6 ##
...
return out_file.getValue() ## insert after 24 ##
使用方法是:myImage = add_watermark(photo_image)
。然后创建HTTP头部,并用myImage
输出。简单来说,我们是把JPG图片保存到StringIO中,然后用getValue()来读取它。
另外,可以看看Mark的分支,它叠加了一张图片。
假设你有一个服务器上的图片地址,叫做 Photo.image_url。
你可以用下面这个视图函数来返回带水印的图片:
from PIL import Image
from django.core.servers.basehttp import FileWrapper
from django.http import StreamingHttpResponse
def render_image_with_watermark(request, pk, text):
# pk is the primary key of photo model
photo = get_object_or_404(Photo, pk=pk)
# watermark the photo and save it to a temp file
tmp_name = tempfile.mktemp()
# this function was introduced in:
# http://www.pythoncentral.io/watermark-images-python-2x/
add_watermark(photo.image_url, text, out_file=tmp_name, angle=23, opacity=0.25)
# render the watermarked photo to response
wrapper = FileWrapper(open(photo.image_url, 'rb'))
response = StreamingHttpResponse(wrapper, 'image/jpeg')
response['Content-Length'] = os.path.getsize(photo.image_url)
response['Content-Disposition'] = 'attachment; filename=photo.jpg'
return response
如果你想让所有的图片都带水印,首先可以让上面的 render_image_with_watermark 这个视图函数有一个网址:
# urls.py
urlpatterns = patterns('',
url(r'^photo/(?P<pk>\d+)/$', 'render_image_with_watermark', name='render_image_with_watermark'),
...
)
完成这个后,试着访问网址 /photo/photo.pk,如果成功的话,它会直接显示出图片。
接着,修改你的 showimage.html 模板:
{% extends 'base.html'%}
{%block title%}{%endblock%}
{%block content%}
{% load endless %}
<div class="container" >
<div class="row mt" style="padding-top:0px; margin-top:10px;">
<ul class="grid effect-2" id="grid">
{% paginate 40 photo_list %}
{% for photo in photo_list%}
{% if photo.approved%}
<li><a href = "{% url 'download_image' photo.id %}">
<!-- ATTENTION HERE -->
<img src={% url 'render_image_with_watermark' pk=photo.id %} alt = 'sample photo' /></a>
</li>
{%endif%}
{% endfor %}
</ul>
</div><!-- row -->
</div><!-- container -->
<p>{%show_more%}</p>
{%endblock%}
试试看。