在Django中使用PIL创建图片水印

3
我有一个基于图像的应用程序。用户上传图像,如果由管理员批准,则在网页上显示。这些图像不可供未购买特定计划的用户使用。用户必须购买计划,然后才能下载这些图像。但是我们知道右键单击可以保存图像,因此在这些图像上添加水印会更安全。因此,我决定使用PIL添加水印。
我在这里找到了一个教程:http://www.pythoncentral.io/watermark-images-python-2x/。但是,我不确定如何在我的Django应用程序中实现它,因为我很新手Python和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个回答

3
免责声明:本人是水印教程的作者。 附加信息:针对网站输出,以下为更改内容:
 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的分支,其中覆盖图像

1
假设您拥有图像的服务器端url: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视图创建一个URL:
# 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%}

试一试。


我已经尝试了你上面的代码,现在没有图片显示,只有替代图标显示。 - Md. Tanvir Raihan
照片的image_url是否正确指向了服务器端的原始图像路径?@user2971215 - Alfred Huang
首先,您应该尝试我建议的URL。您是否看到水印照片正确呈现了?在此之前,请使用您的HTML模板进行调试。 - Alfred Huang
我使用了 'photo.image_url',但它不起作用,然后我尝试了 'photo.url',但它也不起作用。 - Md. Tanvir Raihan
render_image_with_watermark视图只是将图像文件流写入HTTP响应,如果您的图像存储在数据库中,您也可以更改代码以获取文件流。 - Alfred Huang
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接