ODOO13 有同志留言,想看看图片上传增加水印。今天,他来撩

2024-04-24 09:58

本文主要是介绍ODOO13 有同志留言,想看看图片上传增加水印。今天,他来撩,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

图片上传增加水印,本文使用Python第三方库 PIL 实现上传图片增加水印。本文只说明如何将odoo中的图片,转化为二进制的形式,并在二进制数据流的基础上使用PIL库,为图片增加水印,并不代表任何实际业务。

为了演示,我假定模型下有如下Image类型的字段:

class Test(models.Model):_name = 'test.test'_description = 'demo'image_1920 = fields.Image(default=_default_image)

在xml中显示: 

<field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/>

为了在创建或修改次图片字段时,都能进行增加水印的处理,我将处理功能增加到 onchange 事件中。在开始处理图片之前,你需要做如下准备:

1、安装PIL库:

pip3 install pillow

2、下载一个字体包,把它放到static/src/fonts文件夹下,保证此字体兼容中英文,不会出现乱码就可以,我使用的汉体。

链接: https://pan.baidu.com/s/1zdNGonN35WeEROk22NZa_Q 提取码: gsmb

文字水印

对图片增加文字水印的大体思路,是将文字做成一张背景透明的图片,然后与原图片合成。

from odoo import models, fields, api
import base64
from io import BytesIO
import io
from PIL import Image, ImageFont, ImageDraw
from odoo.modules.module import get_module_resourceclass Test(models.Model):_name = 'test.test'_description = 'demo'image_1920 = fields.Image(default=_default_image)@api.onchange("image_1920")def onchange_image_by(self):if self.image_1920:# 默认文字水印,如果没有配置文字,将使用此文字default_font_txt = "HELLO WORLD" # 配置的文字水印font_txt = self.env['ir.config_parameter'].sudo().get_param('product.watermark', default_font_txt) font_path = get_module_resource('test_water_mark', 'static/src/fonts', 'ht.ttc')image = Image.open(BytesIO(base64.b64decode(self.image_1920))).convert('RGBA')# 为文字创建图片txt = Image.new('RGBA', image.size, (0, 0, 0, 0))font_size = int(txt.size[0] / 10)font_obj = ImageFont.truetype(font_path, font_size)draw = ImageDraw.Draw(txt)text_size_x, text_size_y = draw.textsize(font_txt, font=font_obj)draw.text(((txt.size[0] - text_size_x) / 2, (txt.size[1] - text_size_y) / 2),font_txt, font=font_obj, fill=(255, 255, 255, 150))# 合并原图与文字图片out = Image.alpha_composite(image, txt)out = out.convert('RGB')stream = io.BytesIO()out.save(stream, format="PNG")self.write({"image_1920": base64.b64encode(stream.getvalue())})else:pass

实现onchage部分的代码,就已经实现图片增加文字水印的功能了。在上面的代码中,你可能注意到了如下代码:

font_txt = self.env['ir.config_parameter'].sudo().get_param('product.watermark', default_font_txt)

我为了不将水印的文字内容写死,特意在系统参数中定义了一个参数键值对,创建文件 /data/data.xml 并在manifest中引用。这样的话,用户就可以在系统参数里设置文字水印的内容并使用自己定义的文字了:

<?xml version="1.0" encoding="utf-8"?>
<odoo><data noupdate="1"><record model="ir.config_parameter" id="watermark" ><field name="key">product.watermark</field><field name="value">ZERONE</field></record></data>
</odoo>

然后就是如何加载odoo目录下的静态文件(字体包)了,odoo 提供了访问静态资源文件的方法 get_module_resource,但需要你导入这个方法:

from odoo.modules.module import get_module_resource

使用它时,为这个方法提供几个参数,第一个参数是模块名,第二个是存放路径,第三个是文件名:

font_path = get_module_resource('test_water_mark', 'static/src/fonts', 'ht.ttc')

接下来,就是如何将字段 image_1920 转化为Image可识别的流?一般情况下,兄弟们都是从某路径下拿到一张图片,然后将其进行open操作,但有些情况下,我们直接拿到的是二进制数据,而并不是一张已经存在的图片,而我们又不想先将数据转存成一张图片临时存储到服务器的某个角落。怎么办?如果有个东西 能直接在内存中读写二进制数据 就好了。所以BytesIO来了。

image = Image.open(BytesIO(base64.b64decode(self.image_1920))).convert('RGBA')

接下来,就是创建一张背景透明的文字图片,并与原图片合成最终带水印的图片。使用io.BytesIO转为二进制流,给image_1920 字段赋值。


图片水印

图片水印的实现,与文字水印类似,也可以说两种实现就是一种实现,图片水印的实现,简单写个例子吧。下面这个例子,我为了省时,就不创建配置图片水印的视图了,图片水印我使用公司logo。当然,你也可以在模块中,增加一个图片作为默认水印图片,访问静态资源的方法已再上面例子中说明了,此处我省略了。

 就在此处上传公司logo,使用logo 作为图片水印,下面是处理代码:

    @api.onchange("image_1920")def onchange_image_by(self):if self.image_1920:image = Image.open(BytesIO(base64.b64decode(self.image_1920)))logo_as_mask = Image.open(BytesIO(base64.b64decode(self.env["res.company"].sudo().search([],limit=1).logo)))image_size = image.sizelogo_as_mark_size = logo_as_mask.size# 缩放到原图的60%scale = min(int(image_size[0] * 0.6 / logo_as_mark_size[0]), int(image_size[1] * 0.6 / logo_as_mark_size[1]))new_size = (int(logo_as_mark_size[0] * scale), int(logo_as_mark_size[1] * scale))new_mask = logo_as_mask.resize(new_size, resample=Image.ANTIALIAS)# 合并图片image.paste(new_mask, (int((image_size[0] - new_size[0]) / 2), int((image_size[1] - new_size[1]) / 2)), new_mask)stream = io.BytesIO()image.save(stream, format=image.format)self.write({"image_1920": base64.b64encode(stream.getvalue())})else:pass

这次合并图片使用了paste,感兴趣的可以去了解Pil库。下面是实现的效果:

这篇关于ODOO13 有同志留言,想看看图片上传增加水印。今天,他来撩的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/931429

相关文章

uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)

《uni-app小程序项目中实现前端图片压缩实现方式(附详细代码)》在uni-app开发中,文件上传和图片处理是很常见的需求,但也经常会遇到各种问题,下面:本文主要介绍uni-app小程序项目中实... 目录方式一:使用<canvas>实现图片压缩(推荐,兼容性好)示例代码(小程序平台):方式二:使用uni

C#实现高性能拍照与水印添加功能完整方案

《C#实现高性能拍照与水印添加功能完整方案》在工业检测、质量追溯等应用场景中,经常需要对产品进行拍照并添加相关信息水印,本文将详细介绍如何使用C#实现一个高性能的拍照和水印添加功能,包含完整的代码实现... 目录1. 概述2. 功能架构设计3. 核心代码实现python3.1 主拍照方法3.2 安全HBIT

Android实现图片浏览功能的示例详解(附带源码)

《Android实现图片浏览功能的示例详解(附带源码)》在许多应用中,都需要展示图片并支持用户进行浏览,本文主要为大家介绍了如何通过Android实现图片浏览功能,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

Python使用FastAPI实现大文件分片上传与断点续传功能

《Python使用FastAPI实现大文件分片上传与断点续传功能》大文件直传常遇到超时、网络抖动失败、失败后只能重传的问题,分片上传+断点续传可以把大文件拆成若干小块逐个上传,并在中断后从已完成分片继... 目录一、接口设计二、服务端实现(FastAPI)2.1 运行环境2.2 目录结构建议2.3 serv

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

SpringBoot+RustFS 实现文件切片极速上传的实例代码

《SpringBoot+RustFS实现文件切片极速上传的实例代码》本文介绍利用SpringBoot和RustFS构建高性能文件切片上传系统,实现大文件秒传、断点续传和分片上传等功能,具有一定的参考... 目录一、为什么选择 RustFS + SpringBoot?二、环境准备与部署2.1 安装 RustF

Java实现将HTML文件与字符串转换为图片

《Java实现将HTML文件与字符串转换为图片》在Java开发中,我们经常会遇到将HTML内容转换为图片的需求,本文小编就来和大家详细讲讲如何使用FreeSpire.DocforJava库来实现这一功... 目录前言核心实现:html 转图片完整代码场景 1:转换本地 HTML 文件为图片场景 2:转换 H

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

Java实现在Word文档中添加文本水印和图片水印的操作指南

《Java实现在Word文档中添加文本水印和图片水印的操作指南》在当今数字时代,文档的自动化处理与安全防护变得尤为重要,无论是为了保护版权、推广品牌,还是为了在文档中加入特定的标识,为Word文档添加... 目录引言Spire.Doc for Java:高效Word文档处理的利器代码实战:使用Java为Wo

基于C#实现PDF转图片的详细教程

《基于C#实现PDF转图片的详细教程》在数字化办公场景中,PDF文件的可视化处理需求日益增长,本文将围绕Spire.PDFfor.NET这一工具,详解如何通过C#将PDF转换为JPG、PNG等主流图片... 目录引言一、组件部署二、快速入门:PDF 转图片的核心 C# 代码三、分辨率设置 - 清晰度的决定因