基于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 struct模块解析
Jun 12 Python
Python中if __name__ == '__main__'作用解析
Jun 29 Python
python利用正则表达式提取字符串
Dec 08 Python
python XlsxWriter模块创建aexcel表格的实例讲解
May 03 Python
Python3.4 tkinter,PIL图片转换
Jun 21 Python
python tornado微信开发入门代码
Aug 24 Python
Python写一个基于MD5的文件监听程序
Mar 11 Python
Python判断对象是否为文件对象(file object)的三种方法示例
Apr 26 Python
Django发送邮件和itsdangerous模块的配合使用解析
Aug 10 Python
Python使用matplotlib 模块scatter方法画散点图示例
Sep 27 Python
PYQT5开启多个线程和窗口,多线程与多窗口的交互实例
Dec 13 Python
Appium中scroll和drag_and_drop根据元素位置滑动
Feb 15 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类
2006/11/25 PHP
简单分析ucenter 会员同步登录通信原理
2014/08/25 PHP
ThinkPHP 表单自动验证运用示例
2014/10/13 PHP
PHP将Excel导入数据库及数据库数据导出至Excel的方法
2015/06/24 PHP
php实现基于PDO的预处理示例
2017/03/28 PHP
PHP基于SPL实现的迭代器模式示例
2018/04/22 PHP
firebug的一个有趣现象介绍
2011/11/30 Javascript
jQuery获取和设置表单元素的方法
2014/02/14 Javascript
js动态移动滚动条至底部示例代码
2014/04/24 Javascript
angularjs在ng-repeat中使用ng-model遇到的问题
2016/01/21 Javascript
JS Array创建及concat()split()slice()的使用方法
2016/06/03 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
微信小程序 利用css实现遮罩效果实例详解
2017/01/21 Javascript
JS中的数组转变成JSON格式字符串的方法
2017/05/09 Javascript
解决axios post 后端无法接收数据的问题
2019/10/29 Javascript
微信小程序onShareTimeline()实现分享朋友圈
2021/01/07 Javascript
[07:40]DOTA2每周TOP10 精彩击杀集锦vol.4
2014/06/25 DOTA
[01:06]欢迎来到上海,TI9
2018/08/26 DOTA
python清除字符串里非数字字符的方法
2015/07/02 Python
Python Requests 基础入门
2016/04/07 Python
关于python列表增加元素的三种操作方法
2018/08/22 Python
python递归法实现简易连连看小游戏
2020/03/25 Python
利用keras使用神经网络预测销量操作
2020/07/07 Python
详解Python流程控制语句
2020/10/28 Python
详解python polyscope库的安装和例程
2020/11/13 Python
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
2010/07/20 HTML / CSS
英国最大的百货公司:Harrods
2016/08/18 全球购物
银行个人求职自荐信范文
2013/12/16 职场文书
平面设计专业大学生职业规划书
2014/03/12 职场文书
服务理念口号
2014/06/11 职场文书
争当四好少年演讲稿
2014/09/13 职场文书
2014年艾滋病防治工作总结
2014/12/10 职场文书
元宵节寄语大全
2015/02/27 职场文书
python - asyncio异步编程
2021/04/06 Python
python geopandas读取、创建shapefile文件的方法
2021/06/29 Python
Python四款GUI图形界面库介绍
2022/06/05 Python