在Django中将图像保存为临时文件

1 投票
1 回答
9093 浏览
提问于 2025-04-18 08:32

我刚接触Python和Django,最近用Django开发了一个项目。在这个项目里,所有的图片都有水印。我用下面的代码给所有图片加了水印……

from PIL import Image
    def image_watermark(request,image_id):
        photo = Photo.objects.get(pk=image_id)
        watermark = Image.open('{0}/{1}'.format(settings.MEDIA_ROOT,'wmark.png'))
        img = Image.open(photo.photo.file)

        img.paste(watermark,(img.size[0]-watermark.size[0],img.size[1]- watermark.size[1]),watermark)

        img.save('{0}/{1}'.format(settings.MEDIA_ROOT,photo.photo.name), quality=80)


        wrapper = FileWrapper(open(photo.photo.url, 'rb'))
        response = StreamingHttpResponse(wrapper, 'image/jpeg')
        response['Content-Length'] = os.path.getsize(photo.photo.url)
        response['Content-Disposition'] = 'attachment; filename=photo.jpg'
        return response

现在我所有的图片都有水印了。但问题是,作为用户,如果我下载这些图片,我发现下载下来的图片也是有水印的。我想下载的是没有水印的原图,应该怎么解决这个问题呢?

1 个回答

5

你需要把带水印的图片存储到一个不同的文件里。首先,你需要创建一个新的列来存放带水印的图片。

class Photo(models.Model):
    ...
    watermarked_photo = ImageField()

然后,当你把带水印的图片保存到那个列里时。

from PIL import Image
def image_watermark(request,image_id):
    photo = Photo.objects.get(pk=image_id)

    # Only need to watermark when there's no watermark
    if not photo.watermarked_photo.name:
        photo.watermarked_photo.name = 'watermarked_' + photo.photo.name
        watermark = Image.open('{0}/{1}'.format(settings.MEDIA_ROOT,'wmark.png'))
        img = Image.open(photo.photo.file)
        img.paste(watermark,(img.size[0]-watermark.size[0],img.size[1]- watermark.size[1]),watermark)
        img.save('{0}/{1}'.format(settings.MEDIA_ROOT, photo.watermarked_photo.name), quality=80)
        photo.save()

    wrapper = FileWrapper(open(photo.watermarked_photo.url, 'rb'))
    response = StreamingHttpResponse(wrapper, 'image/jpeg')
    response['Content-Disposition'] = 'attachment; filename=photo.jpg'
    return response

我的Django技能有点生疏,所以这段代码可能需要一些修改才能正常工作。不过这个思路应该是没问题的。

如果你只想使用一个临时文件,那就试试这个。

from PIL import Image
import tempfile

def image_watermark(request,image_id):
    photo = Photo.objects.get(pk=image_id)
    watermark = Image.open('{0}/{1}'.format(settings.MEDIA_ROOT,'wmark.png'))
    img = Image.open(photo.photo.file)
    img.paste(watermark,(img.size[0]-watermark.size[0],img.size[1]- watermark.size[1]),watermark)

    tmpfile = tempfile.TemporaryFile()
    img.save(tmpfile, img.format, quality=80)

    tmpfile.seek(0)
    wrapper = FileWrapper(tmpfile)
    response = StreamingHttpResponse(wrapper, 'image/jpeg')
    response['Content-Disposition'] = 'attachment; filename=photo.jpg'
    return response

撰写回答