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

相关文章

Python实现精准提取 PDF中的文本,表格与图片

《Python实现精准提取PDF中的文本,表格与图片》在实际的系统开发中,处理PDF文件不仅限于读取整页文本,还有提取文档中的表格数据,图片或特定区域的内容,下面我们来看看如何使用Python实... 目录安装 python 库提取 PDF 文本内容:获取整页文本与指定区域内容获取页面上的所有文本内容获取

Python基于微信OCR引擎实现高效图片文字识别

《Python基于微信OCR引擎实现高效图片文字识别》这篇文章主要为大家详细介绍了一款基于微信OCR引擎的图片文字识别桌面应用开发全过程,可以实现从图片拖拽识别到文字提取,感兴趣的小伙伴可以跟随小编一... 目录一、项目概述1.1 开发背景1.2 技术选型1.3 核心优势二、功能详解2.1 核心功能模块2.

Go语言如何判断两张图片的相似度

《Go语言如何判断两张图片的相似度》这篇文章主要为大家详细介绍了Go语言如何中实现判断两张图片的相似度的两种方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 在介绍技术细节前,我们先来看看图片对比在哪些场景下可以用得到:图片去重:自动删除重复图片,为存储空间"瘦身"。想象你是一个

使用Python实现base64字符串与图片互转的详细步骤

《使用Python实现base64字符串与图片互转的详细步骤》要将一个Base64编码的字符串转换为图片文件并保存下来,可以使用Python的base64模块来实现,这一过程包括解码Base64字符串... 目录1. 图片编码为 Base64 字符串2. Base64 字符串解码为图片文件3. 示例使用注意

c/c++的opencv实现图片膨胀

《c/c++的opencv实现图片膨胀》图像膨胀是形态学操作,通过结构元素扩张亮区填充孔洞、连接断开部分、加粗物体,OpenCV的cv::dilate函数实现该操作,本文就来介绍一下opencv图片... 目录什么是图像膨胀?结构元素 (KerChina编程nel)OpenCV 中的 cv::dilate() 函

GitLab文件的上传与下载方式

《GitLab文件的上传与下载方式》:本文主要介绍GitLab文件的上传与下载方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录GitLab 项目拉取到本地GitLab 项目上传方法方法 1:本地项目未初始化Git方法 2:本地项目已初始化GitGitLab 上

使用Python实现调用API获取图片存储到本地的方法

《使用Python实现调用API获取图片存储到本地的方法》开发一个自动化工具,用于从JSON数据源中提取图像ID,通过调用指定API获取未经压缩的原始图像文件,并确保下载结果与Postman等工具直接... 目录使用python实现调用API获取图片存储到本地1、项目概述2、核心功能3、环境准备4、代码实现

Nginx 413修改上传文件大小限制的方法详解

《Nginx413修改上传文件大小限制的方法详解》在使用Nginx作为Web服务器时,有时会遇到客户端尝试上传大文件时返回​​413RequestEntityTooLarge​​... 目录1. 理解 ​​413 Request Entity Too Large​​ 错误2. 修改 Nginx 配置2.1

Java应用如何防止恶意文件上传

《Java应用如何防止恶意文件上传》恶意文件上传可能导致服务器被入侵,数据泄露甚至服务瘫痪,因此我们必须采取全面且有效的防范措施来保护Java应用的安全,下面我们就来看看具体的实现方法吧... 目录恶意文件上传的潜在风险常见的恶意文件上传手段防范恶意文件上传的关键策略严格验证文件类型检查文件内容控制文件存储

CentOS7增加Swap空间的两种方法

《CentOS7增加Swap空间的两种方法》当服务器物理内存不足时,增加Swap空间可以作为虚拟内存使用,帮助系统处理内存压力,本文给大家介绍了CentOS7增加Swap空间的两种方法:创建新的Swa... 目录在Centos 7上增加Swap空间的方法方法一:创建新的Swap文件(推荐)方法二:调整Sww