基于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文档生成工具pydoc使用介绍
Jun 02 Python
python fabric实现远程部署
Jan 05 Python
python3使用PyMysql连接mysql数据库实例
Feb 07 Python
python 以16进制打印输出的方法
Jul 09 Python
Python实现App自动签到领取积分功能
Sep 29 Python
对Python3之进程池与回调函数的实例详解
Jan 22 Python
Python字典的基本用法实例分析【创建、增加、获取、修改、删除】
Mar 05 Python
Python-Seaborn热图绘制的实现方法
Jul 15 Python
关于python pycharm中输出的内容不全的解决办法
Jan 10 Python
TensorFlow tensor的拼接实例
Jan 19 Python
pycharm 2020.2.4 pip install Flask 报错 Error:Non-zero exit code的问题
Dec 04 Python
Python爬虫爬取全球疫情数据并存储到mysql数据库的步骤
Mar 29 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
php 日期时间处理函数小结
2009/12/18 PHP
php _autoload自动加载类与机制分析
2012/02/10 PHP
zf框架的校验器InArray使用示例
2014/03/13 PHP
11个PHPer必须要了解的编程规范
2014/09/22 PHP
20个2014年最优秀的PHP框架回顾
2014/10/22 PHP
php判断文件夹是否存在不存在则创建
2015/04/09 PHP
通过chrome浏览器控制台(Console)进行PHP Debug的方法
2016/10/19 PHP
[企业公众号]升级到[企业微信]之后发送消息失败的解决方法
2017/06/30 PHP
php正确输出json数据的实例讲解
2018/08/21 PHP
聊聊 PHP 8 新特性 Attributes
2020/08/19 PHP
用Javascript读取中文COOKIE的解决办法
2007/02/15 Javascript
jQuery定义插件的方法
2015/12/18 Javascript
Bootstrap中文本框的宽度变窄并且加入一副验证码图片的实现方法
2016/06/23 Javascript
用jmSlip编写移动端顶部日历选择控件
2016/10/24 Javascript
jQuery鼠标移动图片上实现放大效果
2017/06/25 jQuery
angularjs实现猜大小功能
2017/10/23 Javascript
Vue自定义过滤器格式化数字三位加一逗号实现代码
2018/03/23 Javascript
Angular2之二级路由详解
2018/08/31 Javascript
TypeScript基础入门教程之三重斜线指令详解
2018/10/22 Javascript
vue解决使用$http获取数据时报错的问题
2019/10/30 Javascript
PYTHON正则表达式 re模块使用说明
2011/05/19 Python
Python数据类型详解(二)列表
2016/05/08 Python
玩转python selenium鼠标键盘操作(ActionChains)
2020/04/12 Python
Python操作Access数据库基本步骤分析
2016/09/19 Python
python 判断是否为正小数和正整数的实例
2017/07/23 Python
基于Python和Scikit-Learn的机器学习探索
2017/10/16 Python
python使用Plotly绘图工具绘制气泡图
2019/04/01 Python
Python中Numpy ndarray的使用详解
2019/05/24 Python
Python多进程multiprocessing、进程池用法实例分析
2020/03/24 Python
Python基于Hypothesis测试库生成测试数据
2020/04/29 Python
DBA的职责都有哪些
2012/05/16 面试题
三分钟演讲稿事例
2014/03/03 职场文书
刊首寄语大全
2014/04/11 职场文书
学生上课看漫画的检讨书
2014/09/26 职场文书
深入理解margin塌陷和margin合并的解决方案
2021/06/26 HTML / CSS
游戏《铁拳》动画化!2022年年内播出
2022/03/21 日漫