基于django micro搭建网站实现加水印功能


Posted in Python onMay 22, 2020

用django_micro搭建的,给图片加文字水印的前端+后端功能开发;

大体功能是:输入水印的文字,选择要加水印的图片,最后生成加好水印的图片。

可在一页中显示多个加好水印的图片,且可点击显示或隐藏图片的缩略图。实现效果如下:

基于django micro搭建网站实现加水印功能

基于django micro搭建网站实现加水印功能

代码如下

from django_micro import route, run, configure
from django.http import HttpRequest, HttpResponse
from dominate.document import document
import dominate.tags as dom
from wand.drawing import Drawing   # 加水印用
from wand.image import Image  # 加水印用
import base64  # 图片转字符串用
 
 
configure({'DEBUG':True})
 
# 一些元素的cls
CENTERFRAME = "flex flex-col items-center justify-center bg-teal-200 h-screen"
UPLOAD_FORM_ATTRIS ={
  "class":"flex flex-col justify-center",
  "ic-post-to": "/file",
  "ic-target": "#result_item",
  "ic-replace-target": "true",
  "enctype": "multipart/form-data"
}
CARD1 = "flex flex-col bg-green-400 shadow-xl p-1 rounded-lg w-80 h-auto"
TEXT_INPUT = "shadow border rounded m-1 p-1 text-base text-center font-thin"
CARD2 = "flex flex-col bg-white shadow-xl p-2 rounded-lg w-80 h-80"
DASHED_BOX = "flex flex-col items-center justify-center border-dashed border-2 border-gray-200 h-full"
UPLOAD_ICON = "fas fa-file-upload text-gray-300 font-medium text-6xl"
UPLOAD_BUTTON = "flex justify-center bg-green-400 px-3 py-2 mt-4 text-white rounded shadow"
RESULT_CONTAINER = "flex flex-col bg-white items-center"
RESULT_ITEM = "flex flex-col justify-center bg-white p-2 border-t border-gray-200 w-64"
TOGGLE_TEXT_ATTRIS = {   # 这个常量后来没用
  "ic-action":"slideToggle",
  # "ic-target":"#toggle_img", # 以ID定位,只能选择第一个元素
  "ic-target":"figure"   # 以元素类型定位,会对所有同类元素进行操作
}
 
 
# 为了写head部分的引入方便,写个link_函数;下面script_函数类似
def link_(lk):
  return dom.link(rel="stylesheet",type="text/css",href=lk)
 
def script_(s):
  return dom.script(src=s)
 
def page():
  doc = document()
  with doc.head:
    link_("https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css") # tailwind
    link_("https://extra-uru1z3cxu.now.sh/css/extra.css") # 额外写的扩展库
    link_("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.8.2/css/all.css") # 为了使用font-awesome的图标
    script_("https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js") # jquery
    script_("http://intercoolerjs.org/release/intercooler-1.2.2.js")  # intercooler
  with doc.body:
    with dom.div(cls=CENTERFRAME) as CenterFrame:
      with dom.form(UPLOAD_FORM_ATTRIS) as UploadForm:
        # 输入水印文字区
        with dom.div(cls=CARD1) as Card1:
          dom.p("Write down your mark here",cls="text-base font-thin text-white" )
          dom.input(cls=TEXT_INPUT,id="wm_text",type="text",name="mark_text",placeholder="your watermark text")
        # 上传图片区
        with dom.div(cls=CARD2) as Card2:
          with dom.div(cls=DASHED_BOX):
            dom.i(cls=UPLOAD_ICON,onclick='''$('#fileupload').click()''')
            dom.p("Find File", id="show_info", cls="text-gray-500 mt-4")
            dom.button("Upload", cls=UPLOAD_BUTTON)
            dom.input(cls="hidden", type="file", id="fileupload",name="ori_img",
                 onchange='''$('#show_info').text(this.value.split("\\\\").pop(-1))''')
 
      # 生成水印图片区
      with dom.div(cls=RESULT_CONTAINER) as ResultContainer:
        dom.span(id="result_item")
 
  return doc.render()
 
 
def item(result_file_path):
  filename = result_file_path.split('/',1)[-1].split('.')[0]
  print('filename:',filename)
  # 处理图片,转成字符串
  with open(result_file_path, "rb") as imageFile:
    img_str = base64.b64encode(imageFile.read())
 
  with dom.div(cls=RESULT_ITEM) as ResultItem:
    with dom.a( {
      "ic-action":"slideToggle",
      "ic-target":f"#{filename}"
    }) as ToggleText:
      dom.p(filename, cls="text-sm font-thin text-center text-gray-800")
    with dom.figure(cls="hidden",id=filename): # id中不能带'.'(点)
      dom.img(title="data src",alt="",
          src = "data:image/jpeg;base64," + str(img_str,'utf-8') ) # 转str时要加'utf-8',否则不能去掉b'
 
  return dom.span(id="result_item").render() + ResultItem.render()
 
 
@route('')
def index(request: HttpRequest):
  return HttpResponse(page())
 
@route('file')
def filehandler(request:HttpRequest):
  ori_img = request.FILES.get('ori_img')
  mark_text = request.POST.get('mark_text') # 得用request.POST,因为form提交是用POST方式
  print('mark_text:',mark_text)
  result_file_path = 'output/Toggle_'+ori_img.name  # 打水印后的文件保存路径
 
  with Image(file=ori_img) as img:
    # 先保存原始图片
    img.save(filename='userupload/' + ori_img.name)
    # 画图,把字画在原图上
    with Drawing() as ctx:
      ctx.font_family = 'Times New Roman, Nimbus Roman No9'
      # ctx.font_size = 50
      ctx.font_size = int(img.height) * 0.1
      ctx.text_kerning = 20 # 字间距
      ctx.fill_color = 'grey'
      # ctx.opacity = 0.9  # 不透明性
      img.annotate(mark_text, ctx, left=int(img.width) * 0.1, baseline=int(img.height) * 0.45)
    img.save(filename=result_file_path)
 
  return HttpResponse(item(result_file_path))
 
app = run()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python读写Redis数据库操作示例
Mar 18 Python
将Emacs打造成强大的Python代码编辑工具
Nov 20 Python
详解Python map函数及Python map()函数的用法
Nov 16 Python
20个常用Python运维库和模块
Feb 12 Python
Python 绘图库 Matplotlib 入门教程
Apr 19 Python
Python命令行参数解析工具 docopt 安装和应用过程详解
Sep 26 Python
Python制作简易版小工具之计算天数的实现思路
Feb 13 Python
python读取csv文件指定行的2种方法详解
Feb 13 Python
keras训练曲线,混淆矩阵,CNN层输出可视化实例
Jun 15 Python
python如何提升爬虫效率
Sep 27 Python
Python如何telnet到网络设备
Feb 18 Python
如何利用Python实现n*n螺旋矩阵
Jan 18 Python
基于Tensorflow一维卷积用法详解
May 22 #Python
Python参数传递机制传值和传引用原理详解
May 22 #Python
python filecmp.dircmp实现递归比对两个目录的方法
May 22 #Python
关于keras.layers.Conv1D的kernel_size参数使用介绍
May 22 #Python
Python参数传递对象的引用原理解析
May 22 #Python
Python configparser模块常用方法解析
May 22 #Python
keras中的卷积层&池化层的用法
May 22 #Python
You might like
最小化数据传输――在客户端存储数据
2006/10/09 PHP
在同一窗体中使用PHP来处理多个提交任务
2008/05/08 PHP
10条PHP编程习惯助你找工作
2008/09/29 PHP
php生成二维码
2015/08/10 PHP
js string 转 int 注意的问题小结
2013/08/15 Javascript
jQuery 无刷新分页实例代码
2013/11/12 Javascript
js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS
2013/11/18 Javascript
JavaScript中的异常捕捉介绍
2014/12/31 Javascript
读Javascript高性能编程重点笔记
2016/12/21 Javascript
js判断手机号是否正确并返回的实现代码
2017/01/17 Javascript
借助node实战JSONP跨域实例
2017/03/30 Javascript
基于Vue2x实现响应式自适应轮播组件插件VueSliderShow功能
2018/05/16 Javascript
vue-cli中vue本地实现跨域调试接口
2019/01/16 Javascript
基于vue实现滚动条滚动到指定位置对应位置数字进行tween特效
2019/04/18 Javascript
实例详解vue中的$root和$parent
2019/04/29 Javascript
在Express中提供静态文件的实现方法
2019/10/17 Javascript
Vue Object 的变化侦测实现代码
2020/04/15 Javascript
JS+canvas五子棋人机对战实现步骤详解
2020/06/04 Javascript
vue项目接口管理,所有接口都在apis文件夹中统一管理操作
2020/08/13 Javascript
微信小程序中target和currentTarget的区别小结
2020/11/06 Javascript
JavaScript 判断浏览器是否是IE
2021/02/19 Javascript
[02:01]2018完美盛典-开场舞《双子星》
2018/12/16 DOTA
python中的__slots__使用示例
2015/02/26 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
Python之pymysql的使用小结
2019/07/01 Python
使用selenium和pyquery爬取京东商品列表过程解析
2019/08/15 Python
解决pycharm最左侧Tool Buttons显示不全的问题
2019/12/17 Python
详细分析Python collections工具库
2020/07/16 Python
Django解决frame拒绝问题的方法
2020/12/18 Python
Redbubble法国:由独立艺术家设计的独特产品
2019/01/08 全球购物
我能否用void** 指针作为参数, 使函数按引用接受一般指针
2013/02/16 面试题
毕业生医学检验求职信
2013/10/16 职场文书
幼儿园教学管理制度
2014/02/04 职场文书
公共艺术专业自荐信
2014/09/01 职场文书
幼儿园开学家长寄语(2016秋季)
2015/12/03 职场文书
golang DNS服务器的简单实现操作
2021/04/30 Golang