基于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的web框架编写前端模版的教程
Apr 30 Python
python计算一个序列的平均值的方法
Jul 11 Python
Python中的并发处理之asyncio包使用的详解
Apr 03 Python
Python自然语言处理 NLTK 库用法入门教程【经典】
Jun 26 Python
浅谈python3.6的tkinter运行问题
Feb 22 Python
解决Python3 抓取微信账单信息问题
Jul 19 Python
把django中admin后台界面的英文修改为中文显示的方法
Jul 26 Python
Python中断多重循环的思路总结
Oct 04 Python
python把一个字符串切开的实例方法
Sep 27 Python
4款Python 类型检查工具,你选择哪个呢?
Oct 30 Python
Python3.9.1中使用split()的处理方法(推荐)
Feb 07 Python
使用Python解决图表与画布的间距问题
Apr 11 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 MySql增删改查的简单实例
2016/06/21 PHP
PDO::prepare讲解
2019/01/29 PHP
jQuery 处理网页内容的实现代码
2010/02/15 Javascript
jQuery 阴影插件代码分享
2012/01/09 Javascript
用js来定义浏览器中一个左右浮动元素相对于页面主体宽度的位置的函数
2012/01/21 Javascript
Extjs 3.3切换tab隐藏相应工具栏出现空白解决
2013/04/02 Javascript
js实现幻灯片效果(基于jquery插件)
2013/11/05 Javascript
流量统计器如何鉴别C#:WebBrowser中伪造referer
2015/01/07 Javascript
JavaScript父子窗体间的调用方法
2015/03/31 Javascript
精通JavaScript的this关键字
2020/05/28 Javascript
javascript弹出窗口中增加确定取消按钮
2016/06/24 Javascript
用jQuery向div中添加Html文本内容的简单实现
2016/07/13 Javascript
Javascript调试之console对象——你不知道的一些小技巧
2017/07/10 Javascript
Mongoose实现虚拟字段查询的方法详解
2017/08/15 Javascript
JS实现快速比较两个字符串中包含有相同数字的方法
2017/09/11 Javascript
从零开始搭建webpack+react开发环境的详细步骤
2018/05/18 Javascript
vue实现自定义多选与单选的答题功能
2018/07/05 Javascript
animate.css在vue项目中的使用教程
2018/08/05 Javascript
Vue 实现手动刷新组件的方法
2019/02/19 Javascript
nodejs实现用户登录路由功能
2019/05/22 NodeJs
Node.js API详解之 dgram模块用法实例分析
2020/06/05 Javascript
Python中itertools模块用法详解
2014/09/25 Python
Python应用03 使用PyQT制作视频播放器实例
2016/12/07 Python
Python只用40行代码编写的计算器实例
2017/05/10 Python
Python 多核并行计算的示例代码
2017/11/07 Python
目前最全的python的就业方向
2018/06/05 Python
使用IDLE的Python shell窗口实例详解
2019/11/19 Python
Python configparser模块配置文件过程解析
2020/03/03 Python
详解CSS3选择器:nth-child和:nth-of-type之间的差异
2017/09/18 HTML / CSS
Snapfish英国:在线照片打印和个性化照片礼品
2017/01/13 全球购物
Glamest意大利:女性在线奢侈品零售店
2019/04/28 全球购物
大学学风建设方案
2014/05/04 职场文书
2015年元旦活动总结
2014/05/09 职场文书
创建绿色学校先进个人材料
2014/08/20 职场文书
MySQL的安装与配置详细教程
2021/06/26 MySQL
不同品牌、不同型号对讲机如何互相通联
2022/02/18 无线电