用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()
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
广告合作:本站广告合作请联系QQ:858582 申请时备注:广告合作(否则不回)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
暂无评论...
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
2024年11月24日
2024年11月24日
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]