【Go】:图片上添加水印的全面指南——从基础到高级特性
前言
在数字内容日益重要的今天,保护版权和标识来源变得关键。为图片添加水印有助于声明所有权、提升品牌认知度,并防止未经授权的使用。本文将介绍如何用Go语言实现图片水印,包括静态图片和带旋转、倾斜效果的文字水印,帮助您有效保护数字内容。我们将逐步解析关键步骤,确保清晰易懂。
一、准备工作
为了顺利实现图片水印功能,您需要完成以下几个准备步骤:
1.安装Go语言环境:确保您的开发环境中已经安装了Go语言,并具备基本的Go编程知识。
2.安装必要的库:
- golang.org/x/image/draw:支持高质量缩放及其他图像绘制操作。
- github.com/disintegration/imaging:提供简便的API用于图像变换,如旋转和倾斜。
3.准备图像资源:
- 主图 (Base Image):这是您想要添加水印的原始图像。它可以是任何您有权处理的图像文件。
- 水印图 (Watermark Image):这是将被放置在主图之上的图像,通常是一个透明背景的PNG文件,这样可以确保它不会遮挡主图的重要细节。
确保您拥有上述所有工具和资源后,就可以开始编写代码来实现图片水印功能了。接下来的章节将逐步指导您如何加载主图、应用水印图并保存最终结果。
二、图片加水印
2.1 图片水印
2.1.1 打开主图
首先,我们需要打开并读取主图文件。这一步确保了程序能够访问到用户想要处理的原始图像。
// 打开主图文件
mainImageFile, err := os.Open("main.png")
if err != nil {log.Fatalf("Failed to open main image: %v", err)
}
defer mainImageFile.Close()
2.1.2 解码主图
接下来,从输入流中读取原始图像并解码它。如果解码过程中出现问题,程序将返回错误信息。这里我们使用image.Decode函数自动识别图像格式。
mainImageFile, err := os.Open("main.png")
if err != nil {log.Fatalf("Failed to open main image: %v", err)
}
defer mainImageFile.Close()
2.1.3 打开水印图片
然后,我们需要打开水印图片文件。与主图类似,我们也需要确保能够正确读取和解码水印图像。
// 打开水印图片
watermarkImageFile, err := os.Open("logo.png") // 可以替换为其他图片文件名
if err != nil {log.Fatalf("Failed to open watermark image: %v", err)
}
defer watermarkImageFile.Close()
2.1.4 解码水印图片
接下来,从输入流中读取水印图像并解码它。如果解码过程中出现问题,程序将返回错误信息。这里我们再次使用image.Decode函数自动识别图像格式。
// 解码水印
watermarkImage, _, err := image.Decode(watermarkImageFile)
if err != nil {log.Fatalf("Failed to decode watermark image: %v", err)
}
2.1.5 计算缩放比例
为了保证水印不会过于显眼或遮挡过多内容,根据原始图像的尺寸计算水印的最大宽度和高度。通常,我们会设定最大值为原始图像宽高的25%。然后基于这些最大值计算出适当的缩放比例。
// 获取主图和水印的边界矩形
mainImageBounds := mainImage.Bounds()
watermarkImageBounds := watermarkImage.Bounds()// 计算水印的最大尺寸
maxWatermarkWidth := int(float64(mainImageBounds.Max.X) * 0.25) // 最大宽度为主图宽度的25%
maxWatermarkHeight := int(float64(mainImageBounds.Max.Y) * 0.25) // 最大高度为主图高度的25%// 计算水印的缩放比例
scale := 1.0
if watermarkImageBounds.Max.X > maxWatermarkWidth || watermarkImageBounds.Max.Y > maxWatermarkHeight {scale = math.Min(float64(maxWatermarkWidth)/float64(watermarkImageBounds.Max.X),float64(maxWatermarkHeight)/float64(watermarkImageBounds.Max.Y),)
}// 应用缩放比例
watermarkWidth := int(float64(watermarkImageBounds.Max.X) * scale)
watermarkHeight := int(float64(watermarkImageBounds.Max.Y) * scale)
2.1.6 创建新的图像
创建一个新的RGBA图像,其大小与原始图像相同,并将原始图像复制到这个新图像中。
// 创建一个新的图像,大小与主图相同
resultImage := image.NewRGBA(mainImageBounds)// 将主图复制到新图像中
draw.Draw(resultImage, mainImageBounds, mainImage, mainImageBounds.Min, draw.Src)
2.1.7 缩放水印图像
根据前面计算的缩放比例调整水印图像的大小。我们可以使用golang.org/x/image/draw包中的draw.CatmullRom.Scale方法来进行高质量缩放。
// 创建一个用于存放缩放后水印的新图像
resizedWatermarkImage := image.NewRGBA(image.Rect(0, 0, watermarkWidth, watermarkHeight))// 使用高质量缩放算法缩放水印图像
draw.CatmullRom.Scale(resizedWatermarkImage, resizedWatermarkImage.Bounds(), watermarkImage, watermarkImageBounds, draw.Over, nil)
2.1.8 确定水印位置
根据用户提供的参数确定水印应该放置的位置,例如左上角、右上角等。对于每个预设的位置,我们计算出相应的坐标点。这里仅给出右下角的例子:
// 引入 position 变量,并赋值为一个有效的水印位置常量
position := "left_top" // 假设使用 "left_top" 作为示例// 计算水印放置的位置
var watermarkX, watermarkY int
switch position {
case "left_top":watermarkX = int(float64(mainImageBounds.Max.X) * 0.02) // 2% of the widthwatermarkY = int(float64(mainImageBounds.Max.Y) * 0.02) // 2% of the height
case "right_top":watermarkX = int(float64(mainImageBounds.Max.X)*0.98) - watermarkWidth // 98% of the width minus watermark widthwatermarkY = int(float64(mainImageBounds.Max.Y) * 0.02) // 2% of the height
case "left_bottom":watermarkX = int(float64(mainImageBounds.Max.X) * 0.02) // 2% of the widthwatermarkY = int(float64(mainImageBounds.Max.Y)*0.98) - watermarkHeight // 98% of the height minus watermark height
case "right_bottom":watermarkX = int(float64(mainImageBounds.Max.X)*0.98) - watermarkWidth // 98% of the width minus watermark widthwatermarkY = int(float64(mainImageBounds.Max.Y)*0.98) - watermarkHeight // 98% of the height minus watermark height
default:log.Fatalf("Invalid watermark position: %v", position)
}
2.1.9 绘制水印
最后,使用draw.Draw方法将调整后的水印绘制到新图像的指定位置。
// 将水印绘制到新图像的指定位置
draw.Draw(resultImage, image.Rectangle{Min: image.Point{X: watermarkX, Y: watermarkY},Max: image.Point{X: watermarkX + watermarkWidth, Y: watermarkY + watermarkHeight},
}, resizedWatermarkImage, image.Point{X: 0, Y: 0}, draw.Over)
2.1.10 绘制旋转水印(可选)
为了让水印更加多样化,可以引入旋转或倾斜的效果。这可以通过创建一个仿射变换矩阵并应用于文字图像来完成。以下是实现旋转功能的代码片段:
// 创建一个新的图像,大小与水印相同
rotatedWatermarkImage := image.NewRGBA(resizedWatermarkImage.Bounds())// 引入 rotation 变量,并赋值为一个有效的旋转角度(度数)
rotation := 45.0 // 假设使用 45.0 度作为示例// 计算旋转角度的弧度
radians := rotation * math.Pi / 180.0// 计算旋转后的中心点
centerX := float64(watermarkWidth) / 2.0
centerY := float64(watermarkHeight) / 2.0// 遍历每个像素点并应用旋转
for y := 0; y < watermarkHeight; y++ {for x := 0; x < watermarkWidth; x++ {// 将像素点转换为相对于中心点的坐标relX := float64(x) - centerXrelY := float64(y) - centerY// 应用旋转矩阵newX := relX*math.Cos(radians) - relY*math.Sin(radians)newY := relX*math.Sin(radians) + relY*math.Cos(radians)// 将旋转后的坐标转换回图像坐标newX += centerXnewY += centerY// 如果旋转后的坐标在图像范围内,则绘制像素if newX >= 0 && newX < float64(watermarkWidth) && newY >= 0 && newY < float64(watermarkHeight) {rotatedWatermarkImage.Set(int(newX), int(newY), resizedWatermarkImage.At(x, y))}}
}// 将旋转后的水印绘制到新图像的指定位置
draw.Draw(resultImage, image.Rectangle{Min: image.Point{X: watermarkX, Y: watermarkY}, Max: image.Point{X: watermarkX + watermarkWidth, Y: watermarkY + watermarkHeight}}, rotatedWatermarkImage, image.Point{X: 0, Y: 0}, draw.Over)
2.1.11 保存结果图像
根据原始图像的格式(如PNG或JPEG),将带有水印的新图像编码并保存到内存中的缓冲区,然后再写入磁盘。
// 保存结果图像到内存
var buffer bytes.Buffer
switch fileExtension {
case ".png":err = png.Encode(&buffer, resultImage)
case ".jpg", ".jpeg":err = jpeg.Encode(&buffer, resultImage, nil)
default:log.Fatalf("Unsupported file extension: %v", fileExtension)
}
if err != nil {log.Fatalf("Failed to encode image: %v", err)
}// 保存结果图像到文件
outputFileName := "output" + fileExtension
outputFile, err := os.Create(outputFileName)
if err != nil {log.Fatalf("Failed to create output file: %v", err)
}
defer outputFile.Close()// 将内存中的图像数据写入文件
_, err = buffer.WriteTo(outputFile)
if err != nil {log.Fatalf("Failed to write to output file: %v", err)
}
2.1.12 完整代码和效果
package mainimport ("bytes""golang.org/x/image/draw""image""image/jpeg""image/png""log""os""path/filepath"
)func main() {// 打开主图文件mainImageFile, err := os.Open("main.png")if err != nil {log.Fatalf("Failed to open main image: %v", err)}defer mainImageFile.Close()// 获取文件扩展名fileExtension := filepath.Ext(mainImageFile.Name())// 解码主图mainImage, _, err := image.Decode(mainImageFile)if err != nil {log.Fatalf("Failed to decode main image: %v", err)}// 打开水印图片watermarkImageFile, err := os.Open("logo.png") // 你可以将 "logo.png" 替换为 "logo.jpg" 或其他图片文件名if err != nil {log.Fatalf("Failed to open watermark image: %v", err)}defer watermarkImageFile.Close()// 解码水印watermarkImage, _, err := image.Decode(watermarkImageFile)if err != nil {log.Fatalf("Failed to decode watermark image: %v", err)}// 获取主图和水印的边界矩形mainImageBounds := mainImage.Bounds()watermarkImageBounds := watermarkImage.Bounds()// 计算水印的最大尺寸maxWatermarkWidth := int(float64(mainImageBounds.Max.X) * 0.20) // 你可以将 "0.20" 替换为 "0.15" 或其他值maxWatermarkHeight := int(float64(mainImageBounds.Max.Y) * 0.20) // 你可以将 "0.20" 替换为 "0.15" 或其他值// 计算水印的缩放比例watermarkWidth := watermarkImageBounds.Max.XwatermarkHeight := watermarkImageBounds.Max.Y// 计算缩放比例scale := 1.0if watermarkWidth > maxWatermarkWidth {scale = float64(maxWatermarkWidth) / float64(watermarkWidth)}if watermarkHeight > maxWatermarkHeight {if scale > float64(maxWatermarkHeight)/float64(watermarkHeight) {scale = float64(maxWatermarkHeight) / float64(watermarkHeight)}}// 应用缩放比例watermarkWidth = int(float64(watermarkWidth) * scale)watermarkHeight = int(float64(watermarkHeight) * scale)// 创建一个新的图像,大小与主图相同resultImage := image.NewRGBA(mainImageBounds)// 将主图复制到新图像中draw.Draw(resultImage, mainImageBounds, mainImage, mainImageBounds.Min, draw.Src)// 缩放水印图像resizedWatermarkImage := image.NewRGBA(image.Rect(0, 0, watermarkWidth, watermarkHeight))draw.NearestNeighbor.Scale(resizedWatermarkImage, resizedWatermarkImage.Bounds(), watermarkImage, watermarkImageBounds, draw.Over, nil)// 引入 position 变量,并赋值为一个有效的水印位置常量position := "left_top" // 假设使用 "left_top" 作为示例// 计算水印放置的位置var watermarkX, watermarkY intswitch position {case "left_top":watermarkX = int(float64(mainImageBounds.Max.X) * 0.02) // 宽度的2%watermarkY = int(float64(mainImageBounds.Max.Y) * 0.02) // 高度的2%case "right_top":watermarkX = int(float64(mainImageBounds.Max.X)*0.98) - watermarkWidth // 宽度的98%减去水印宽度watermarkY = int(float64(mainImageBounds.Max.Y) * 0.02) // 高度的2%case "left_bottom":watermarkX = int(float64(mainImageBounds.Max.X) * 0.02) // 宽度的2%watermarkY = int(float64(mainImageBounds.Max.Y)*0.98) - watermarkHeight // 高度的98%减去水印高度case "right_bottom":watermarkX = int(float64(mainImageBounds.Max.X)*0.98) - watermarkWidth // 宽度的98%减去水印宽度watermarkY = int(float64(mainImageBounds.Max.Y)*0.98) - watermarkHeight // 高度的98%减去水印高度default:log.Fatalf("Invalid watermark position: %v", position)}// 将水印绘制到新图像的指定位置draw.Draw(resultImage, image.Rectangle{Min: image.Point{X: watermarkX, Y: watermarkY}, Max: image.Point{X: watermarkX + watermarkWidth, Y: watermarkY + watermarkHeight}}, resizedWatermarkImage, image.Point{X: 0, Y: 0}, draw.Over)// 保存结果图像到内存var buffer bytes.Bufferswitch fileExtension {case ".png":err = png.Encode(&buffer, resultImage)case ".jpg", ".jpeg":err = jpeg.Encode(&buffer, resultImage, nil)default:log.Fatalf("Unsupported file extension: %v", fileExtension)}if err != nil {log.Fatalf("Failed to encode image: %v", err)}// 保存结果图像到文件outputFile, err := os.Create("output" + fileExtension)if err != nil {log.Fatalf("Failed to create output file: %v", err)}defer outputFile.Close() // 添加文件关闭操作// 将内存中的图像数据写入文件_, err = buffer.WriteTo(outputFile)if err != nil {log.Fatalf("Failed to write to output file: %v", err)}
}
2.2 文字水印
敬请期待!!!
总结
通过以上步骤,我们不仅完成了在图片上添加静态图片水印的功能实现,还增加了旋转、倾斜的水印功能,使得生成的水印更加多样化和个性化。您可以根据自己的需求进一步优化代码,比如支持更多的水印位置选项,或者允许用户上传自定义水印图片。希望这篇文章能帮助您理解和实现这一常见但非常有用的功能。如果您有任何问题或遇到困难,请随时查阅相关文档或寻求社区的帮助。
相关文章:
【Go】:图片上添加水印的全面指南——从基础到高级特性
前言 在数字内容日益重要的今天,保护版权和标识来源变得关键。为图片添加水印有助于声明所有权、提升品牌认知度,并防止未经授权的使用。本文将介绍如何用Go语言实现图片水印,包括静态图片和带旋转、倾斜效果的文字水印,帮助您有…...
R语言的语法糖
R语言的语法糖 引言 在编程语言中,所谓的“语法糖”是指那些使得程序员能够以更简洁、直观的方式书写代码的语法形式。R语言作为一种用于统计分析和数据可视化的编程语言,具有丰富的功能和灵活的语法。本文将深入探讨R语言中的语法糖,帮助读…...
乙游的尽头是虚拟偶像吗?
眼花了,竟然看到二次元乙游男主角走红毯了。 12月20日,某国际知名奢侈品品牌宣布,《恋与深空》四位男主将受邀出席品牌在上海举办的TF戏瘾之夜活动,并公开了四位男主的红毯照片。 没有真人实体的乙游男主走红毯?这是…...
【源码+文档+调试讲解】农产品研究报告管理系统
摘 要 农产品研究报告管理系统是一个旨在收集、整理、存储和分析农产品相关研究数据的综合性平台。农产品研究报告管理系统通常包含一个强大的数据库,它能够处理大量的研究数据,并对这些数据进行有效的管理和备份。农产品研究报告管理系统是现代农业科学…...
SQL UNION 操作符
SQL UNION 操作符 SQL UNION 操作符用于合并两个或多个 SELECT 语句的结果集。它将多个结果集组合成一个单独的结果集,并去除重复的行。为了使用 UNION,每个 SELECT 语句必须具有相同的列数,并且对应列的数据类型必须兼容。 语法 SELECT c…...
springboot vue uniapp 仿小红书 1:1 还原 (含源码演示)
线上预览: 移动端 http://8.146.211.120:8081/ 管理端 http://8.146.211.120:8088/ 小红书凭借优秀的产品体验 和超高人气 目前成为笔记类产品佼佼者 此项目将详细介绍如何使用Vue.js和Spring Boot 集合uniapp 开发一个仿小红书应用,凭借uniapp 可以在h5 小程序 app…...
扩散模型学习
扩散模型学习 DDPM(参考1) DDIM(参考1,参考2)...
【面试】MySQL 最左匹配原则
MySQL的最左匹配原则是在使用联合索引时非常重要的概念,理解并合理运用该原则能显著提升查询性能。以下从多个方面详细介绍: 1. 联合索引结构基础 联合索引是对多个列创建的索引。在MySQL中,联合索引以多列值的组合形式,按照创建…...
Mac 删除ABC 输入法
参考链接:百度安全验证 Mac下删除系统自带输入法ABC,正解!_mac删除abc输入法-CSDN博客 ABC 输入法和搜狗输入法等 英文有冲突~~ 切换后还会在英文状态,可以删除 ;可能会对DNS 输入有影响,但是可以通过复…...
Nginx代理同域名前后端分离项目的完整步骤
前后端分离项目,前后端共用一个域名。通过域名后的 url 前缀来区别前后端项目。 以 vue php 项目为例。直接上 server 模块的 nginx 配置。 server{ listen 80; #listen [::]:80 default_server ipv6onlyon; server_name demo.com;#二配置项目域名 index index.ht…...
21、Transformer Masked loss原理精讲及其PyTorch逐行实现
1. Transformer结构图 2. python import torch import torch.nn as nn import torch.nn.functional as Ftorch.set_printoptions(precision3, sci_modeFalse)if __name__ "__main__":run_code 0batch_size 2seq_length 3vocab_size 4logits torch.randn(batch…...
CNN张量输入形状和特征图
CNN张量输入形状和特征图 这个是比较容易理解的张量的解释,比较直观 卷积神经网络 在这个神经网络编程系列中,我们正在逐步构建一个卷积神经网络(CNN),所以让我们看看CNN的张量输入。 在最后两篇文章中&…...
RK3399开发板Linux实时性改造
本次测试基于NanoPC-T4开发板(国产化处理器RK3399),4.19.111内核Xenomai实时性改造测试。 Xenomai下载网站:https://xenomai.org/downloads/ NanoPC-T4网站:https://wiki.friendlyarm.com/wiki/index.php/NanoPC-T4/z…...
ASP.NET Core 中的高效后台任务管理
一、引言 在当今快速发展的 Web 开发领域,ASP.NET Core 凭借其卓越的性能、强大的功能和高度的灵活性,已然成为众多开发者构建现代 Web 应用程序的首选框架。它不仅能够高效地处理各种复杂的业务逻辑,还为开发者提供了丰富多样的工具和功能&…...
Spring Boot 2 学习指南与资料分享
Spring Boot 2 学习资料 Spring Boot 2 学习资料 Spring Boot 2 学习资料 在当今竞争激烈的 Java 后端开发领域,Spring Boot 2 凭借其卓越的特性,为开发者们开辟了一条高效、便捷的开发之路。如果你渴望深入学习 Spring Boot 2,以下这份精心…...
知识追踪模型DKT,DLKT详解及代码复现
定义与应用 知识追踪是一种 教育技术领域的重要方法 ,旨在通过分析学生的学习行为和表现,预测其掌握特定知识点的程度。这种方法的核心在于建立能够反映学习者认知状态的动态模型,从而实现对学生学习进度的实时监控和个性化指导。 DKT模型 DKT模型 是最早的知识追踪模型之…...
一类特殊积分的计算
一类特殊积分的计算 前言一、第一个引理二、第二个引理三、积分的计算后记 前言 今天讨论的这类积分是十分有趣的,在 Mathematics Stack Exchange 看见后,便打算在此将其中的计算过程完善一下。在本篇文章中,我们重点考虑求解如下积分&#…...
VScode 配置 C语言环境
遇到的问题集合 mingw官方下载网站(https://sourceforge.net/projects/mingw-w64/files/)更新之后,与网上大多数教程上写的界面不同了。 网上大多数教程让下载这个: 但是现在找不到这个文件。 写hello.c文件时,报错&…...
spring mvc源码学习笔记之十一
pom.xml 内容如下 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…...
小结:路由器和交换机的指令对比
路由器和交换机的指令有一定的相似性,但也有明显的区别。以下是两者指令的对比和主要差异: 相似之处 基本操作 两者都支持类似的基本管理命令,比如: 进入系统视图:system-view查看当前配置:display current…...
ffmpeg7.0 aac转pcm
#pragma once #define __STDC_CONSTANT_MACROS #define _CRT_SECURE_NO_WARNINGSextern "C" { #include "libavcodec/avcodec.h" }//缓冲区大小(缓存5帧数据) #define AUDIO_INBUF_SIZE 40960 /*name depthu8 8s16 …...
C#读取本地网络配置信息全攻略
一、引言 在当今数字化时代,网络已深度融入我们生活与工作的方方面面。对于软件开发而言,掌握本地计算机的网络配置信息显得尤为关键。想象一下,你正在开发一款网络诊断工具,需要精准定位网络连接问题,此时 IP 地址、…...
解决aerich init -t xx 报错ModuleNotFoundError: No module named ‘tomli_w‘
今天在学习fastapi的时候,发现一款数据库迁移工具,通过这个工具可以根据模型类来对数据库做出改变。 随跟着学: 在执行 aerich init -t settings.TORTOISE_ORM的时候, 彼其娘之。。 报了一些错误: Traceback (most recent ca…...
python检测gitlab中某个标签在一个月内添加和移除了多少次
可以通过 Python 脚本和 GitLab API 检测一个标签在一个月内被添加和移除的次数。以下是实现的步骤和示例代码: 步骤 获取 GitLab API 访问令牌:在 GitLab 中生成一个 Personal Access Token。设置时间范围:确定一个月的时间范围。调用 Git…...
学习模板之一
学习目标: 提示:这里可以添加学习目标 例如: 一周掌握 Java 入门知识 学习内容: 提示:这里可以添加要学的内容 例如: 搭建 Java 开发环境掌握 Java 基本语法掌握条件语句掌握循环语句 学习时间&#x…...
2025-微服务—SpringCloud-1~3
2025-微服务—SpringCloud 第一章、从Boot和Cloud版本选型开始说起1、Springboot版本2、Springcloud版本3、Springcloud Alibaba4、本次讲解定稿版 第二章 关于Cloud各种组件的停更/升级/替换1、微服务介绍2、SpringCloud是什么?能干吗?产生背景…...
centos7.6 安装nginx 1.21.3与配置ssl
1 安装依赖 yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel2 下载Nginx wget http://nginx.org/download/nginx-1.21.3.tar.gz3 安装目录 mkdir -p /data/apps/nginx4 安装 4.1 创建用户 创建用户nginx使用的nginx用户。 #添加www组 # groupa…...
PL/SQL语言的数据库交互
PL/SQL语言的数据库交互 引言 在当今的信息化时代,数据库管理系统(DBMS)在各行各业中扮演着至关重要的角色。为了高效地与数据库进行交互,许多程序员、数据库管理员和系统分析师选择使用PL/SQL(Procedural Language/…...
ARP欺骗
文章目录 ARP协议ARP欺骗原理断网攻击ARP欺骗(不断网) ARP协议 在局域网中,网络传输的是帧,帧里面有目标主机的MAC地址。arp协议负责将IP地址解析成对应的MAC地址 ARP欺骗原理 即通过伪造IP地址和MAC地址实现ARP欺骗,能够在网络中产生大量…...
Genymotion配套VirtualBox所在地址
在 Genymotion打开虚拟机前需要先打开VirtualBox中的虚拟机 C:\Program Files\Oracle\VirtualBox\VirtualBox.exe 再开启genymotion中的虚拟机开关...
TPS61022 PFM的机制以及TPS61xxx转换器的PFM与PWM之间的负载阈值
引言 TI 的大多数 TPS61xxx 低压升压转换器都配备了 PSM(省电模式),以帮助提高轻负载效率。但是,当它处于重负载状态时,输出纹波通常会高于 PWM。此外,PSM 和 PWM 之间的负载电流阈值不会直观地写入数据表中…...
1. npm 常用命令详解
npm 常用命令详解 npm(Node Package Manager)是 Node.js 的包管理工具,用于安装和管理 Node.js 应用中的依赖库。下面是 npm 的一些常用命令及其详细解释和示例代码。 镜像源 # 查询当前使用的镜像源 npm get registry# 设置为淘宝镜像源 …...
黑马linux入门笔记(01)初始Linux Linux基础命令 用户和权限 实用操作
B站 黑马程序员 的视频 BV1n84y1i7td 黑马程序员新版Linux零基础快速入门到精通,全涵盖linux系统知识、常用软件环境部署、Shell脚本、云平台实践、大数据集群项目实战等 增强自控力 冥想慢呼吸绿色锻炼充分休息减少决策次数优先做重要的事情(早晨)融入强自控群控…...
Markdown中甘特图的使用
Markdown中甘特图的使用 1. 前言2. 语法详解2.1 甘特图语法 3. 使用场景及实例4. 小结5. 其他文章快来试试吧🖊️ Markdown中甘特图的使用 👈点击这里也可查看 1. 前言 Markdown 的原生语法不支持绘制图形,但通过扩展模块,我们可…...
Django创建数据表、模型、ORM操作
1、创建项目 django-admin startproject PersonInfosProject 2、创建项目应用,进入PersonInfosProject文件夹,新建index应用,使用命令 cd PersonInfosProject python manage.py startapp 新建完成之后的目录结构 3、新建数据模型…...
No. 31 笔记 | Web安全-SQL手工注入技术学习 Part 2
一、研究背景 背景介绍 SQL注入是一种常见且高危的Web安全漏洞。攻击者可以通过构造恶意SQL查询语句来绕过验证机制,执行未授权操作,如获取敏感信息、篡改数据库内容甚至控制服务器。 研究内容 本笔记探讨以下数据库的手工注入技术: MySQLAc…...
Spring Boot中的扫描注解如何使用
在 Spring Boot 中,扫描注解是指通过注解来告诉 Spring 框架应该扫描哪些包、哪些类或哪些特定的组件,并将其作为 Spring 容器中的 bean 进行管理。Spring Boot 主要通过以下几种注解来实现自动扫描: ComponentScanSpringBootApplicationCom…...
用 Python 从零开始创建神经网络(十九):真实数据集
真实数据集 引言数据准备数据加载数据预处理数据洗牌批次(Batches)训练(Training)到目前为止的全部代码: 引言 在实践中,深度学习通常涉及庞大的数据集(通常以TB甚至更多为单位)&am…...
深入探讨 Vue.js 的动态组件渲染与性能优化
Vue.js 作为一款前端领域中备受欢迎的渐进式框架,以其简单优雅的 API 和灵活性受到开发者的喜爱。在开发复杂应用时,动态组件渲染是一项极其重要的技术,它能够在页面中动态地加载或切换组件,从而显著提升应用的灵活性与用户体验。…...
qml TextArea、TextEdit、TextField、TextInput的区别于联系
在 QML 中,TextArea、TextEdit、TextField 和 TextInput 都是用来接收用户输入的控件,但它们之间有一些区别和联系。 区别: TextArea:用于多行文本输入,可以接收多行文本输入。TextEdit:也用于多行文本输入…...
《探索 PC 端的开源神经网络多模态模型宝藏》
《探索 PC 端的开源神经网络多模态模型宝藏》 一、多模态模型:开启智能交互新纪元二、主流 PC 端开源多模态模型大赏1. Obsidian:轻量级多模态先锋2. GLM-Edge 系列:移动端与 PC 端的全能选手3. Minicpm-llama3-v2.6:紧凑高效的多…...
centos 搭建nginx+配置域名+windows访问
准备工作:一个完整的centos环境,nginx安装包(可以从官网下载)nginx: download 一:centos可能有精简版,部分环境没有相关依赖包, 需要检查以下项: 1.gcc检查:gcc -v(回车后应当有版…...
docker的数据卷和自定义镜像
docker的数据卷: 容器与宿主机之间,或者容器和容器之间的数据共享(目录)。 创建容器的时间,通过指定目录,实现容器于宿主机之间,或者容器和容器之间的数据共享。 容器的生命周期有限,…...
在 Linux 下Ubuntu创建同权限用户
我是因为不小心把最开始创建的用户的文件夹颜色搞没了,再后来全白用习惯了,就不想卸载了,像创建一个和最开始创建的用户有一样的权限可以执行sudo -i进入root一样的用户 如图这是最原始的样子 第一步 创建新用户,我这里是因为之前…...
计算机视觉算法实战——面部特征点检测
✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连 ✨ ✨个人主页欢迎您的访问 ✨期待您的三连✨ 1. 领域介绍✨✨ 面部特征点检测(Facial Landmark Detection)是计算机视觉中…...
电力场景红外测温图像均压环下的避雷器识别分割数据集labelme格式2436张1类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):2436 标注数量(json文件个数):2436 标注类别数:1 标注类别名称:["arrester"] 每个类别标注的框数&am…...
4种革新性AI Agent工作流设计模式全解析
文章目录 导读:AI Agent的四种关键设计模式如下:1. 反思2. 工具使用3. 规划4. 多Agent协作 总结内容简介: 导读: AI Agent是指能够在特定环境中自主执行任务的人工智能系统,不仅接收任务,还自主制定和执行…...
C#基础 枚举 Enumeration从基础到进阶
目录 一、入门篇:枚举基础1. 枚举类型的定义2. 枚举类型的优点3. 枚举的基本使用3.1 枚举的类型转换3.2 遍历枚举成员3.3 判断枚举值是否有效3.4枚举的比较 4. 枚举的设计规范 二、深入底层篇:存储、值与继承限制1. 枚举的存储与表示2. 枚举底层类型选择…...
SOME/IP 协议详解——服务发现
文章目录 1. Introduction (引言)2. SOME/IP Service Discovery (SOME/IP-SD)2.1 General(概述)2.2 SOME/IP-SD Message Format2.2.1 通用要求2.2.2 SOME/IP-SD Header2.2.3 Entry Format2.2.4 Options Format2.2.4.1 配置选项(Co…...
android studio使用DataBinding
DataBinding 是谷歌官方发布的在android上对MVVM设计模式的一个实现框架,其作用是实现数据绑定。 Android DataBinding主要实现了View和ViewModel的双向绑定,包括用户的响应。并且实现了自动更新。 DataBinding优点: 1.大量减少Act…...