基于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 相关文章推荐
Django 添加静态文件的两种实现方法(必看篇)
Jul 14 Python
Python实现求笛卡尔乘积的方法
Sep 16 Python
Python随机生成均匀分布在单位圆内的点代码示例
Nov 13 Python
Python基于列表模拟堆栈和队列功能示例
Jan 05 Python
python RabbitMQ 使用详细介绍(小结)
Nov 08 Python
聊聊python里如何用Borg pattern实现的单例模式
Jun 06 Python
python elasticsearch从创建索引到写入数据的全过程
Aug 04 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
Nov 29 Python
Python 3.8 新功能大揭秘【新手必学】
Feb 05 Python
基于jupyter代码无法在pycharm中运行的解决方法
Apr 21 Python
Python新手如何进行闭包时绑定变量操作
May 29 Python
Python matplotlib 利用随机函数生成变化图形
Apr 26 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数组去除空值函数分享
2015/02/02 PHP
PHP简单获取多个checkbox值的方法
2016/06/13 PHP
php把时间戳转换成多少时间之前函数的实例
2016/11/16 PHP
PHP序列化和反序列化深度剖析实例讲解
2020/12/29 PHP
javascript贪吃蛇完整版(源码)
2013/12/09 Javascript
ECMAScript 5严格模式(Strict Mode)介绍
2015/03/02 Javascript
jQuery实现平滑滚动的标签分栏切换效果
2015/08/28 Javascript
JQuery点击行tr实现checkBox选中的简单实例
2016/05/26 Javascript
node.js操作mysql简单实例
2017/05/25 Javascript
jQuery滚动插件scrollable.js用法分析
2017/05/25 jQuery
实现div滚动条默认最底部以及默认最右边的示例代码
2017/11/15 Javascript
jQuery 改变P标签文本值方法
2018/02/24 jQuery
react项目如何使用iconfont的方法步骤
2019/03/13 Javascript
js中的深浅拷贝问题简析
2019/05/10 Javascript
swiper Scrollbar滚动条组件详解
2019/09/08 Javascript
WEEX环境搭建与入门详解
2019/10/16 Javascript
如何优雅地在Node应用中进行错误异常处理
2019/11/25 Javascript
原生js实现ajax请求和JSONP跨域请求操作示例
2020/03/14 Javascript
微信小程序基于ColorUI构建皮皮虾短视频去水印组件
2020/11/04 Javascript
vue自定义插件封装,实现简易的elementUi的Message和MessageBox的示例
2020/11/20 Vue.js
jQuery实现简单弹幕制作
2020/12/10 jQuery
Python实现Tab自动补全和历史命令管理的方法
2015/03/12 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
scrapy-redis源码分析之发送POST请求详解
2019/05/15 Python
浅析Python3 pip换源问题
2020/01/06 Python
使用Python求解带约束的最优化问题详解
2020/02/11 Python
高考考python编程是真的吗
2020/07/20 Python
Ted Baker美国官网:英国时尚品牌
2018/10/29 全球购物
什么是动态端口(Dynamic Ports)?动态端口的范围是多少?
2014/12/12 面试题
大学生自助营养快餐店创业计划书
2014/01/13 职场文书
英语专业个人求职信范文
2014/02/01 职场文书
乡村文明行动实施方案
2014/03/29 职场文书
工程售后服务承诺书
2014/05/21 职场文书
语文教师个人工作总结
2015/02/06 职场文书
教师工作能力自我评价
2015/03/04 职场文书
2019年教师节活动策划方案
2019/09/09 职场文书