当前位置: 首页 > news >正文

基于TensorFlow.js与Web Worker的智能证件照生成方案

功能简介

本文基于TensorFlow.js与Web Worker实现了常用的“证件照”功能,可以对照片实现抠图并替换背景。值得一提的是,正常抠图的操作应该由后端进行,这里只是主要演示该功能实现步骤,并不建议该功能由前端全权处理。
限于个人技术能力有限,当前功能实现的并不怎么良好,抠图不够精细且缺少对图片处理后的画质修复等操作,这些还请诸位大佬见谅了。

效果演示

原图

在这里插入图片描述## 效果图
在这里插入图片描述

功能亮点

  • 智能人像分割:基于BodyPix模型实现精准人像抠图
  • 实时背景替换:支持动态颜色选择和边缘优化算法
  • 多尺寸适配:预设常用证件照尺寸+自定义毫米级精度
  • 高性能处理:Web Worker独立线程保障主线程流畅性
  • 模型加载优化:按需加载MobileNetV1量化模型
  • 边缘平滑算法:卷积核模糊处理提升证件照专业度

主要逻辑详解

加载模型

// 初始化模型
async function loadModel() {try {console.log('开始加载模型...');if (!bodyPixModel) {bodyPixModel = await bodyPix.load({architecture: 'MobileNetV1',outputStride: 16,multiplier: 0.75,quantBytes: 2});console.log('模型加载成功');}return bodyPixModel;} catch (error) {console.error('模型加载失败:', error);throw error;}
}

该方法的主要作用便是加载bodyPixModel模型,这里用到的模型为MobileNetV1。关于bodyPix模型下load方法的各种参数可以自行搜索一下官方文档查看。

人像分割核心流程

    // 使用 BodyPix 进行人像分割console.log('开始人像分割...');const segmentation = await model.segmentPerson(imgDataForSegmentation, {flipHorizontal: false,internalResolution: 'medium',segmentationThreshold: config.segmentationThreshold || 0.7});console.log('人像分割完成');// 创建输出 Canvasconst outputCanvas = new OffscreenCanvas(img.width, img.height);const outputCtx = outputCanvas.getContext('2d');// 绘制原始图片outputCtx.drawImage(img, 0, 0);// 应用背景色const backgroundColor = hexToRgb(config.bgColor);const outputImageData = outputCtx.getImageData(0, 0, img.width, img.height);const pixelData = outputImageData.data;// 应用分割结果for (let i = 0; i < segmentation.data.length; i++) {const n = i * 4;if (segmentation.data[i] === 0) { // 背景部分pixelData[n] = backgroundColor.r;pixelData[n + 1] = backgroundColor.g;pixelData[n + 2] = backgroundColor.b;pixelData[n + 3] = 255;}}outputCtx.putImageData(outputImageData, 0, 0);

这里的主要逻辑是分割图像及应用选择的背景色。

边缘平滑算法

// 边缘平滑处理
async function smoothEdges(ctx, width, height) {const imageData = ctx.getImageData(0, 0, width, height);const data = imageData.data;const kernel = [[0.075, 0.124, 0.075],[0.124, 0.204, 0.124],[0.075, 0.124, 0.075]];const tempData = new Uint8ClampedArray(data);for (let y = 1; y < height - 1; y++) {for (let x = 1; x < width - 1; x++) {const idx = (y * width + x) * 4;if (isEdgePixel(data, idx, width)) {let r = 0, g = 0, b = 0, a = 0;for (let ky = -1; ky <= 1; ky++) {for (let kx = -1; kx <= 1; kx++) {const offset = ((y + ky) * width + (x + kx)) * 4;const weight = kernel[ky + 1][kx + 1];r += tempData[offset] * weight;g += tempData[offset + 1] * weight;b += tempData[offset + 2] * weight;a += tempData[offset + 3] * weight;}}data[idx] = r;data[idx + 1] = g;data[idx + 2] = b;data[idx + 3] = a;}}}ctx.putImageData(imageData, 0, 0);
}

这里使用3*3卷积核对边缘像素进行了加权平均处理,从而消除锯齿效果。这里用到的isEdgePixel()方法目的是判断一个像素是否为图像的边缘像素,方法是通过比较该像素与其相邻像素的alpha通道值(也就是透明度)。

function isEdgePixel(data, idx, width) {const alpha = data[idx + 3];const leftAlpha = data[idx - 4 + 3];const rightAlpha = data[idx + 4 + 3];const topAlpha = data[idx - width * 4 + 3];const bottomAlpha = data[idx + width * 4 + 3];return (alpha !== leftAlpha || alpha !== rightAlpha || alpha !== topAlpha || alpha !== bottomAlpha);
}

完整代码

IDPhoto.vue

<template><div class="id-photo-container"><!-- 左侧工具栏 --><div class="tools-panel"><el-form :model="photoConfig" label-position="top"><!-- 预设尺寸选择 --><el-form-item label="证件照尺寸"><el-select v-model="photoConfig.selectedSize" placeholder="选择尺寸"><el-optionv-for="size in presetSizes":key="size.value":label="size.label":value="size.value"/></el-select></el-form-item><!-- 自定义尺寸输入 --> <el-form-item label="自定义尺寸(mm)"><div class="custom-size"><el-input-number v-model="photoConfig.customWidth" :min="20" :max="1000"placeholder="宽度"/><span class="separator">×</span><el-input-number v-model="photoConfig.customHeight" :min="20" :max="1000"placeholder="高度"/></div></el-form-item><!-- 背景颜色选择 --><el-form-item label="背景颜色"><el-color-picker v-model="photoConfig.bgColor" /></el-form-item><!-- 操作按钮 --><div class="action-buttons"><el-button type="primary" @click="uploadImage">上传图片</el-button><el-button type="success" :disabled="!hasImage"@click="downloadPhoto">下载证件照</el-button></div></el-form></div><!-- 右侧预览区域 --><div class="preview-panel"><div class="preview-area":style="{ backgroundColor: photoConfig.bgColor }"><img v-if="previewUrl":src="previewUrl"ref="previewImage"@load="handleImageLoad"/><div v-else class="placeholder">请上传图片</div></div></div><!-- 隐藏的文件输入框 --><inputtype="file"ref="fileInput"accept="image/*"style="display: none"@change="handleFileChange"/><el-loading v-model:visible="loading"text="处理中..."background="rgba(255, 255, 255, 0.8)"/></div>
</template><script setup>
import { ref, reactive, onMounted, onUnmounted, watch } from 'vue'
import { ElMessage } from 'element-plus'// 预设尺寸选项
const presetSizes = [{ label: '一寸照片 (25×35mm)', value: '25x35' },{ label: '二寸照片 (35×49mm)', value: '35x49' },{ label: '小二寸 (35×45mm)', value: '35x45' },{ label: '大二寸 (35×53mm)', value: '35x53' }
]// 照片配置
const photoConfig = reactive({selectedSize: '35x45',customWidth: 35,customHeight: 45,bgColor: '#FFFFFF',modelQuality: 'medium', // 可选: 'low', 'medium', 'high'segmentationThreshold: 0.7, // 分割阈值,可调整精度edgeBlur: 3 // 边缘模糊半径
})// 组件引用
const fileInput = ref(null)
const previewImage = ref(null)// 状态变量
const previewUrl = ref('')
const hasImage = ref(false)// 图片处理 Worker
let imageWorker = null// 添加加载状态
const loading = ref(false)// 初始化 Worker
onMounted(() => {try {// 使用 ?worker 查询参数来告诉 Vite 这是一个 worker 文件imageWorker = new Worker(new URL('../../workers/idphoto.worker.js?worker', import.meta.url),{ type: 'module' })imageWorker.onmessage = (e) => {console.log('收到Worker响应:', e.data)if (e.data.status === 'success') {const blobUrl = URL.createObjectURL(e.data.result)previewUrl.value = blobUrlloading.value = false // 确保加载状态被重置} else {console.error('Worker处理失败:', e.data.error)ElMessage.error(`处理图片时出错: ${e.data.error}`)loading.value = false}}imageWorker.onerror = (error) => {console.error('Worker错误:', error)ElMessage.error('图片处理服务初始化失败')loading.value = false}} catch (error) {console.error('创建Worker失败:', error)ElMessage.error('初始化图片处理服务失败')loading.value = false}
})// 清理 Worker
onUnmounted(() => {if (imageWorker) {imageWorker.terminate()}
})// 上传图片
const uploadImage = () => {fileInput.value.click()
}// 处理文件选择
const handleFileChange = async (event) => {const file = event.target.files[0]if (!file) returnif (!file.type.startsWith('image/')) {ElMessage.error('请上传图片文件')return}if (file.size > 10 * 1024 * 1024) { // 10MB 限制ElMessage.error('图片大小不能超过10MB')return}loading.value = trueElMessage.info('正在处理图片,首次使用可能需要加载模型...')const reader = new FileReader()reader.onload = (e) => {const img = new Image()img.onload = () => {console.log('图片加载成功,尺寸:', img.width, 'x', img.height)try {imageWorker.postMessage({imageData: e.target.result,config: {width: img.width,height: img.height,bgColor: photoConfig.bgColor,segmentationThreshold: photoConfig.segmentationThreshold,modelQuality: photoConfig.modelQuality}})} catch (error) {loading.value = falseconsole.error('发送数据到Worker时出错:', error)ElMessage.error('处理图片时出错')}}img.onerror = (error) => {loading.value = falseconsole.error('图片加载失败:', error)ElMessage.error('图片加载失败')}img.src = e.target.resulthasImage.value = true}reader.onerror = (error) => {loading.value = falseconsole.error('读取文件失败:', error)ElMessage.error('读取文件失败')}reader.readAsDataURL(file)
}// 处理图片加载
const handleImageLoad = () => {// 这里可以添加图片加载后的处理逻辑
}// 下载证件照
const downloadPhoto = async () => {if (!hasImage.value) returntry {const response = await fetch(previewUrl.value)const blob = await response.blob()const link = document.createElement('a')link.download = '证件照.png'link.href = URL.createObjectURL(blob)link.click()ElMessage.success('下载成功')} catch (error) {ElMessage.error('下载图片时出错')console.error(error)}
}// 添加背景色变化监听
watch(() => photoConfig.bgColor, (newColor) => {if (hasImage.value && previewUrl.value) {const img = new Image()img.onload = () => {imageWorker.postMessage({imageData: previewUrl.value,config: {width: img.width,height: img.height,bgColor: newColor}})}img.src = previewUrl.value}
})
</script><style scoped>
.id-photo-container {display: flex;gap: 20px;padding: 20px;height: 100%;
}.tools-panel {width: 300px;padding: 20px;background: #f5f7fa;border-radius: 8px;
}.preview-panel {flex: 1;display: flex;justify-content: center;align-items: center;background: #f5f7fa;border-radius: 8px;overflow: hidden;
}.preview-area {width: 80%;height: 80%;display: flex;justify-content: center;align-items: center;background: #fff;border-radius: 4px;box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
}.preview-area img {max-width: 100%;max-height: 100%;object-fit: contain;
}.placeholder {color: #909399;font-size: 16px;
}.custom-size {display: flex;align-items: center;gap: 10px;
}.separator {color: #909399;
}.action-buttons {display: flex;gap: 10px;margin-top: 20px;
}
</style>

idphoto.workder.js

import * as tf from '@tensorflow/tfjs'
import * as bodyPix from '@tensorflow-models/body-pix'let bodyPixModel = null;// 初始化模型
async function loadModel() {try {console.log('开始加载模型...');if (!bodyPixModel) {bodyPixModel = await bodyPix.load({architecture: 'MobileNetV1',outputStride: 16,multiplier: 0.75,quantBytes: 2});console.log('模型加载成功');}return bodyPixModel;} catch (error) {console.error('模型加载失败:', error);throw error;}
}// 处理图片的 Worker
self.onmessage = async function(e) {console.log('Worker 收到消息:', e.data);const { imageData, config } = e.data;try {if (!imageData || !config) {throw new Error('缺少必要的参数')}// 加载模型const model = await loadModel();console.log('模型准备就绪');// 创建图片元素const img = await createImageBitmap(await fetch(imageData).then(r => r.blob()));// 创建离屏 Canvasconst canvas = new OffscreenCanvas(img.width, img.height);const ctx = canvas.getContext('2d');if (!ctx) {throw new Error('无法创建Canvas上下文')}// 绘制原始图片ctx.drawImage(img, 0, 0);console.log('图片绘制完成');// 获取图片数据const imgDataForSegmentation = ctx.getImageData(0, 0, img.width, img.height);// 使用 BodyPix 进行人像分割console.log('开始人像分割...');const segmentation = await model.segmentPerson(imgDataForSegmentation, {flipHorizontal: false,internalResolution: 'medium',segmentationThreshold: config.segmentationThreshold || 0.7});console.log('人像分割完成');// 创建输出 Canvasconst outputCanvas = new OffscreenCanvas(img.width, img.height);const outputCtx = outputCanvas.getContext('2d');// 绘制原始图片outputCtx.drawImage(img, 0, 0);// 应用背景色const backgroundColor = hexToRgb(config.bgColor);const outputImageData = outputCtx.getImageData(0, 0, img.width, img.height);const pixelData = outputImageData.data;// 应用分割结果for (let i = 0; i < segmentation.data.length; i++) {const n = i * 4;if (segmentation.data[i] === 0) { // 背景部分pixelData[n] = backgroundColor.r;pixelData[n + 1] = backgroundColor.g;pixelData[n + 2] = backgroundColor.b;pixelData[n + 3] = 255;}}outputCtx.putImageData(outputImageData, 0, 0);// 优化边缘await smoothEdges(outputCtx, img.width, img.height);// 转换为 Blobconst resultBlob = await outputCanvas.convertToBlob({type: 'image/png'});console.log('处理完成,发送结果');self.postMessage({status: 'success',result: resultBlob});} catch (error) {console.error('Worker处理错误:', error);self.postMessage({status: 'error',error: error.message || '处理图片时发生未知错误'});}
};// 边缘平滑处理
async function smoothEdges(ctx, width, height) {const imageData = ctx.getImageData(0, 0, width, height);const data = imageData.data;const kernel = [[0.075, 0.124, 0.075],[0.124, 0.204, 0.124],[0.075, 0.124, 0.075]];const tempData = new Uint8ClampedArray(data);for (let y = 1; y < height - 1; y++) {for (let x = 1; x < width - 1; x++) {const idx = (y * width + x) * 4;if (isEdgePixel(data, idx, width)) {let r = 0, g = 0, b = 0, a = 0;for (let ky = -1; ky <= 1; ky++) {for (let kx = -1; kx <= 1; kx++) {const offset = ((y + ky) * width + (x + kx)) * 4;const weight = kernel[ky + 1][kx + 1];r += tempData[offset] * weight;g += tempData[offset + 1] * weight;b += tempData[offset + 2] * weight;a += tempData[offset + 3] * weight;}}data[idx] = r;data[idx + 1] = g;data[idx + 2] = b;data[idx + 3] = a;}}}ctx.putImageData(imageData, 0, 0);
}function isEdgePixel(data, idx, width) {const alpha = data[idx + 3];const leftAlpha = data[idx - 4 + 3];const rightAlpha = data[idx + 4 + 3];const topAlpha = data[idx - width * 4 + 3];const bottomAlpha = data[idx + width * 4 + 3];return (alpha !== leftAlpha || alpha !== rightAlpha || alpha !== topAlpha || alpha !== bottomAlpha);
}function hexToRgb(hex) {const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);return result ? {r: parseInt(result[1], 16),g: parseInt(result[2], 16),b: parseInt(result[3], 16)} : null;
} 

以上便是证件照功能的全部逻辑,其实我这里写的相当简陋且具有很大的扩展空间。各位大佬如果有精力,可以在这个基础上 增加服装替换、美颜等功能,以及可以进一步优化UI界面(我这里样式写的不是特别好)。
总之,感谢阅读了,愿你我都能在技术之路上更进一步!

相关文章:

基于TensorFlow.js与Web Worker的智能证件照生成方案

功能简介 本文基于TensorFlow.js与Web Worker实现了常用的“证件照”功能&#xff0c;可以对照片实现抠图并替换背景。值得一提的是&#xff0c;正常抠图的操作应该由后端进行&#xff0c;这里只是主要演示该功能实现步骤&#xff0c;并不建议该功能由前端全权处理。 限于个人技…...

jupyterhub on k8s 配置用户名密码 简单版

如果只是小组内使用 不想共用密码 也不想搞复杂认证方案 那么就直接通过map(用户名,密码md5值)来制定密码 config.yaml部分内容 hub:config:JupyterHub:shutdown_on_logout: true # 用户logout 自动stop jupyter pod,家目录下所有文件会被保存到pvc 即启动后之前家目录下…...

Logic-RL:Unleashing LLM Reasoning with Rule-Based Reinforcement learning

1.Introduction deepseek-r1,kimi-k1.5和openai-o1效果都很好。deepseek-r1引入了一种简单而有效的基于规则的强化学习,无需依赖传统的支撑技术,如蒙特卡洛书树搜索MCTS或者过程奖励模型PRM,便能出现新兴的推理模式。deepseek-r1开源了权重,但是并未发布训练或数据集,这…...

算法-数据结构-图的构建(邻接矩阵表示)

数据定义 //邻接矩阵表示图 //1.无向图是对称的 //2.有权的把a,到b 对应的位置换成权的值/*** 无向图* A B* A 0 1* B 1 0*/ /*** 有向图* A B* A 0 1* B 0 0*/import java.util.ArrayList; import java.util.List;/*** 带权图* A B* A 0 1* B 0 0*/ p…...

使用 Grafana 监控 Spring Boot 应用

随着软件开发领域的不断发展&#xff0c;监控和可观测性已成为确保系统可靠性和性能的关键实践。Grafana 是一个功能强大的开源工具&#xff0c;能够为来自各种来源的监控数据提供丰富的可视化功能。在本篇博客中&#xff0c;我们将探讨如何将 Grafana 与 Spring Boot 应用程序…...

使用S32DS部署Tensorflow lite到S32K3

一、概述 1、本文主要介绍如何用S32DS在NXP S32K344 中部署Tensorflow&#xff1b; 2、示例使用了Tensorflow入门代码&#xff0c;主要功能是识别28 * 28 的手写图片的数字&#xff1b; 3、在MCU上开启DSP功能后&#xff0c;最终运行时间在 7ms&#xff08;64神经元&#xf…...

AWS S3深度解析:十大核心应用场景与高可用架构设计实践

摘要&#xff1a;作为全球领先的对象存储服务&#xff0c;Amazon S3凭借其高扩展性、持久性和安全性&#xff0c;已成为企业云原生架构的核心组件。本文将深入探讨S3的典型技术场景&#xff0c;并揭秘其背后的架构设计逻辑。 一、AWS S3核心技术特性解析 Amazon Simple Storag…...

系统学习算法:专题十二 记忆化搜索

什么是记忆化搜索&#xff0c;我们先用一道经典例题来引入&#xff0c;斐波那契数 题目一&#xff1a; 相信一开始学编程语言的时候&#xff0c;就一定碰到过这道题&#xff0c;在学循环的时候&#xff0c;我们就用for循环来解决&#xff0c;然后学到了递归&#xff0c;我们又…...

Redis基操

redis 存储在内存中 key-value存储 主要存储热点数据(短时间大量的访客去访问) 启动命令 redis-server.exe redis.windows.conf 客户端链接redis服务器 redis-cli.exe redis-cli.exe -h localhost -p 6379 redis-cli.exe -h localhost -p 6379 -a 123456 退出 exit keys * 命…...

基于 GEE 计算并下载研究区年均叶面积指数 LAI 和光合有效辐射分量 FPAR

目录 1 完整代码 2 运行结果 1 完整代码 var table table; var collection ee.ImageCollection(MODIS/061/MOD15A2H).filterDate(2023-01-01, 2023-12-30).filterBounds(table); // LAI配色 var colorLai {min: 0,max: 100,palette: [ffffff, fde0d4, fcc4ac, faa784, f…...

软考——WWW与HTTP

1.万维网&#xff08;world wide web&#xff09; 是一个规模巨大的、可以资源互联的资料空间。由URL进行定位&#xff0c;通过HTTP协议传送给使用者&#xff0c;又由HTML来进行文件的展现。 它的主要组成部分是&#xff1a;URL、HTTP、HTML。 &#xff08;1&#xff09;URL…...

sqli-labs-master第46关

目录 报错注入 直接注入 数据库名 数据库中的表名 users表结构&#xff1a; users表数据&#xff1a; python脚本注入 直接注入 获取数据库名 获取表名 获取表结构 获取数据 布尔盲注 获取数据库名 获取表名 获取表结构 获取数据 报错注入 直接注入 数据库名…...

opencv交叉编译报错:undefined reference to `png_riffle_palette_neon

序偶NEON 概述 NEON&#xff08;Nested Enhanced Vector Instruction Set&#xff09;是 ARM 架构中的一种高级 SIMD&#xff08;Single Instruction, Multiple Data&#xff0c;单指令多数据&#xff09;扩展技术。它专为加速多媒体和信号处理任务而设计&#xff0c;允许在单…...

代码随想录算法训练day63---图论系列7《prim算法kruskal算法》

代码随想录算法训练 —day63 文章目录 代码随想录算法训练前言一、53. 寻宝—prim算法打印出来最小生成树的每条边 二、53. 寻宝—kruskal算法打印出来最小生成树的每条边 总结 前言 今天是算法营的第63天&#xff0c;希望自己能够坚持下来&#xff01; 今天继续图论part&…...

算法日常刷题笔记(2)

为保持刷题的习惯 计划一天刷3-5题 然后一周总计汇总一下 这是第二篇笔记 笔记时间为2月17日到2月23日 第一天 找到初始输入字符串 找到初始输入字符串 Ihttps://leetcode.cn/problems/find-the-original-typed-string-i/ Alice 正在她的电脑上输入一个字符串。但是她打字技…...

C# httpclient 和 Flurl.Http 的测试

关于C#调用接口或Post,Flurl封装了httpclient, CSDN有哥们提供了一个公网的测试网站&#xff0c;可以测试Post调用&#xff0c;我写了2个函数&#xff0c;测试httpclient和Flurl使用Post: async 和 await 是成对使用的&#xff0c;为了接受web异步返回的数据&#xff0c;winfor…...

关于ES中text类型时间字段范围查询的结构化解决方案

前言 有关es中text类型的时间字段范围查询的问题&#xff0c;比如&#xff1a; {"query": {"range": {"insertTime": {"gte": "2025-02-01T00:00:00","lte": "2025-11-30T23:59:59","format&quo…...

四元数 欧拉角

orientation 是表示物体在三维空间中的 旋转姿态 的数据结构。它通常使用 四元数&#xff08;Quaternion&#xff09; 来表示旋转。四元数是一种数学工具&#xff0c;用于描述三维空间中的旋转&#xff0c;相比欧拉角&#xff08;Euler Angles&#xff09;和旋转矩阵&#xff0…...

Linux项目自动化构建工具-make/Makefile (linux第六课)

目录 背景 介绍 依赖关系的格式 依赖方法的格式 原理 背景 会不会写makefile&#xff0c;从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数&#xff0c;其按类型、功能、模块分别放在若干个目录中&#xff0c;makefile定义了一系列的规则来指定…...

Java 登录框架

Java框架中常用的几种成熟的token生成框架对比 - 白露~ - 博客园 SpringBoot整合sa-token&#xff0c;jwt登录及拦截器鉴权Demo_只有在集成 sa-token-jwt 插件后才可以使用 extra 扩展参数-CSDN博客 推荐一款轻量级权限认证框架Sa-Token&#xff0c;集成JWT和Redis轻松实现认…...

人工智能、机器学习、深度学习和大语言模型之间的关系

人工智能&#xff08;AI&#xff09;、机器学习&#xff08;ML&#xff09;、深度学习&#xff08;DL&#xff09;和大语言模型&#xff08;LLM&#xff09;之间是逐层包含且技术递进的关系&#xff0c;具体如下&#xff1a; 1. 层级关系 人工智能&#xff08;AI&#xff09;…...

项目组合管理:优化项目选择与资源分配——从战略到实战的全流程指南

在复杂的商业环境中&#xff0c;企业往往需要同时推进多个项目以支撑战略目标。然而&#xff0c;资源有限、目标冲突、优先级模糊等问题常导致项目失败或资源浪费。项目组合管理&#xff08;Project Portfolio Management, PPM&#xff09; 正是解决这一痛点的系统性方法。它通…...

zabbix排障-zabbix监控的主机出现可用性灰色或者红色问题

目录 解决zabbix-agent可用性灰色的办法: 解决zabbix可用性红色的方法: 在zabbix日常的使用中 我们会遇到很多的问题 就比如今天我做好zabbix-server和zabbix-agent两台机器的配置 然后在wen页面上发现两台主机都有可用性的问题 如下图 解决zabbix-agent可用性灰色的办法: …...

C语言(13)------------>do-while循环

1.do-while循环的语法 我们知道C语言有三大结构&#xff0c;顺序、选择、循环。我们可以使用while循环、for循环、do-while循环实现循环结构。之前的博客中提及到了前两者的技术实现。可以参考&#xff1a; C语言&#xff08;11&#xff09;-------------&#xff1e;while循…...

2025-spring boot 之多数据源管理

1、是使用Spring提供的AbstractRoutingDataSource抽象类 注入多个数据源。 创建 DataSourceConfig 配置类 通过spring jdbc 提供的带路由的抽象数据源 AbstractRoutingDataSource import org.springframework.beans.factory.annotation.Autowired; import org.springframew…...

自动驾驶两个传感器之间的坐标系转换

有两种方式可以实现两个坐标系的转换。 车身坐标系下一个点p_car&#xff0c;需要转换到相机坐标系下&#xff0c;旋转矩阵R_car2Cam&#xff0c;平移矩阵T_car2Cam。点p_car在相机坐标系下记p_cam. 方法1&#xff1a;先旋转再平移 p_cam T_car2Cam * p_car T_car2Cam 需要注…...

DeepSeek 细节之 MoE

DeepSeek 细节之 MoE DeepSeek 团队通过引入 MoE&#xff08;Mixture of Experts&#xff0c;混合专家&#xff09; 机制&#xff0c;以“分而治之”的思想&#xff0c;在模型容量与推理成本之间找到了精妙的平衡点&#xff0c;其中的技术实现和细节值得剖思 Transformer 演变…...

SeaCMS V9海洋影视管理系统报错注入

漏洞背景 SQL 注入攻击是当前网络安全中最常见的一种攻击方式&#xff0c;攻击者可以利用该漏洞访问或操作数据库&#xff0c;造成数据泄露或破坏。通常发生在开发人员未能正确处理用户输入时。 在 SeaCMS V9 中&#xff0c;用户输入&#xff08;如登录、评论、分页、ID 等&a…...

Cannot deserialize instance of java.lang.String out of START_ARRAY token

这个错误 Cannot deserialize instance of java.lang.String out of START_ARRAY token 表示 Jackson 正在尝试将一个 JSON 数组反序列化成一个 String 类型的字段&#xff0c;但是 JSON 中传递的是一个数组而不是单一的字符串。 具体来说&#xff0c;这段堆栈信息&#xff1a…...

LeetCode 解题思路 1(Hot 100)

解题思路&#xff1a; 使用哈希表优化查找&#xff1a;利用哈希表存储已遍历元素的值及其索引&#xff0c;将查找时间从O(n)降至O(1)。一次遍历&#xff1a;遍历数组&#xff0c;对每个元素计算其补数&#xff08;target - nums[i]&#xff09;&#xff0c;若补数存在于哈希表…...

js中的await与async的使用

以下两个方法&#xff0c;区别只在有没有catch&#xff0c;使用的时候却要注意 // 封装请求方法&#xff0c;同步loading状态出去 export const fetchWithLoading async (fn: Function, params: any, loading: Ref) > {loading.value true;try {return await fn(params);…...

蓝耘科技上线 DeepSeek 满血版,500万tokens免费送

&#x1f31f; 嗨&#xff0c;我是Lethehong&#xff01;&#x1f31f; &#x1f30d; 立志在坚不欲说&#xff0c;成功在久不在速&#x1f30d; &#x1f680; 欢迎关注&#xff1a;&#x1f44d;点赞⬆️留言收藏&#x1f680; &#x1f340;欢迎使用&#xff1a;小智初学…...

【入门音视频】音视频基础知识

&#x1f308;前言&#x1f308; 这个系列在我学习过程中&#xff0c;对音视频知识归纳总结的笔记。因为音视频相关讲解非常稀少&#xff0c;所以我希望通过这个音视频系列&#xff0c;跟大家一起学习音视频&#xff0c;希望减少初学者在学习上的压力。同时希望也欢迎指出文章的…...

w~视觉~合集13

我自己的原文哦~ https://blog.51cto.com/whaosoft/13384038 #xxx w视觉合集13~17没了.... #ViTAR 作者提出了一种新颖的架构&#xff1a;任意分辨率的视觉 Transformer &#xff08;ViTAR&#xff09;。ViTAR中的自适应标记合并功能使模型能够自适应地处理可变分辨率图像…...

DeepSeek+Kimi 一键生成100种PPT

一 简介 PPT在工作中经常用到&#xff0c;无论是给老板汇报&#xff0c;还是同事、朋友之间的分享&#xff0c;或是去见投资人:) &#xff0c;都离不开它&#xff0c;然而写PPT经常让人感觉不胜其烦&#xff0c;无论是逻辑的展开、还是页面的布局、字体、配图&#xff0c;都像个…...

【Qt之QQuickWidget】QML嵌入QWidget中

由于我项目开始使用Widgets,换公司后直接使用QML开发&#xff0c;没有了解过如何实现widget到qml过渡&#xff0c;恰逢面试时遇到一家公司希望从widget迁移到qml开发&#xff0c;询问相关实现&#xff0c;一时语塞&#xff0c;很尴尬&#xff0c;粗略研究并总结下。 对qwidget嵌…...

Apache Flink CDC (Change Data Capture) mysql Kafka

比如使用 Flink CDC , 监听mysql bin-log日志实现数据的实时同步, 发送到kafka springboot整合flink cdc监听数据库数据 阿里开源的神仙工具&#xff0c;完美实现数据同步&#xff01;#程序员阿里开源的这个神器很好很强大。阿里开源的这个神器全面超越Canal&#xff0c;果然在…...

Week1_250217~250223_OI日志(待完善)

W1_250217~250223_OI日志 250217大致安排题目 250218大致安排题目 250219大致安排 250217 大致安排 上午讲了树上启发式合并&#xff0c;中午和下午补了上午的题&#xff0c;额外做了一道。 题目 U41492 树上数颜色 &#xff08;老师自己出的&#xff0c;实在是太典中点了&…...

线性模型 - 学习总结

本文对前面博文中所学的机器学习的知识进行总结&#xff0c;以便整体上加深对机器学习的理解。 一、机器学习三要素&#xff1a;模型、学习准则、优化算法 机器学习是从有限的观测数据中学习(或“猜测”)出具有一般性的规律&#xff0c;并 可以将总结出来的规律推广应用到未观…...

IP----访问服务器流程

1.访问服务器流程 1.分层 1.更利于标准化 2.降低层次之间的关联性---每一层都只完成自身层次所执行的功能--每一层都在下层的基础上提供增值服务 1.应用层 抽象语言---编码---提供人机交互的接口 2.表示层 编码--二进制&#xff0c;压缩解压缩、格式转换 3.会话层 建立…...

Visual Studio 中 C/C++ 函数不安全警告(C4996)终极解决方案:分场景实战指南

问题描述 在 Visual Studio 中编写 C/C 代码时&#xff0c;使用 scanf、strcpy、fopen 等传统函数会触发以下警告&#xff1a; C4996: xxx: This function or variable may be unsafe. Consider using xxx_s instead. 根本原因&#xff1a; 这些函数缺乏缓冲区溢出检查&#…...

DeepSeek写俄罗斯方块手机小游戏

DeepSeek写俄罗斯方块手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端俄罗斯方块H5文件&#xff1a; 核心功能要求 原生JavaScript实现&#xff0c;适配手机屏幕 …...

小程序高度问题背景scss

不同的机型&#xff0c;他的比例啥的都会不一样&#xff0c;同样的rpx也会有不同的效果。所以这里选择了取消高度。 <view class"box-border" :style"{padding-top: ${navHeight}px,}"><!-- 已登录 --><view v-if"userStore.userInfo&…...

浅析 DeepSeek 开源的 FlashMLA 项目

浅析 DeepSeek 开源的 FlashMLA 项目 DeepSeek 开源周 Day 1&#xff08;2025 年 2 月 24 日&#xff09;放出的开源项目——FlashMLA&#xff0c;是一款针对 Hopper 架构 GPU 高效多层级注意力 (Multi-Level Attention, MLA) 解码内核&#xff0c;专门为处理变长序列问题而设…...

【Blender】二、建模篇--08,小狐狸角色建模

这堂课呢 我们来完成本套课程建模片的最后一个模型 小狐狸 这堂课呢 主要想让大家一起走一遍角色建模的一个基本流程 让你以后遇到类似的模型时候有一个基本的建模思路 那我们现在就开始吧 2 00:00:16,830 --> 00:00:24,390 我们还是在我们之前建模马拉松的那个文件里面继…...

【Gin-Web】Bluebell社区项目梳理6:限流策略-漏桶与令牌桶

本文目录 一、限流二、漏桶三、令牌桶算法四、Gin框架中实现令牌桶限流 一、限流 限流又称为流量控制&#xff0c;也就是流控&#xff0c;通常是指限制到达系统的并发请求数。 限流虽然会影响部分用户的使用体验&#xff0c;但是能一定程度上保证系统的稳定性&#xff0c;不至…...

MySQL 数据库基础

1. MySQL 数据库基础 在这一部分&#xff0c;我们将学习 MySQL 的基本概念和常见的数据库操作&#xff0c;帮助你掌握如何创建数据库、表&#xff0c;并进行数据的增、删、改操作。同时&#xff0c;我们还会探讨一些常见的错误示例及其原因&#xff0c;帮助你避免常见的陷阱。…...

如何查看java的字节码文件?javap?能用IDEA吗?

编译指令&#xff1a; javac YourProject.java 查看字节码文件的指令&#xff1a; javap -c -l YourProject.class 不添加-c指令就不会显示字节码文件&#xff1a; 不添加 -l 就不会显示源代码和字节码文件的对应关系&#xff1a; 添加-l之后多出来这些&#xff1a; IDEA不太…...

实战技巧:如何快速提高网站收录的权威性?

快速提高网站收录的权威性是一个系统性的工作&#xff0c;涉及内容质量、网站结构、外部链接、用户体验等多个方面。以下是一些实战技巧&#xff0c;可以帮助你快速提升网站收录的权威性&#xff1a; 一、提升内容质量 原创性&#xff1a; 确保网站内容具备高质量与原创性&a…...

详解传输层协议TCP/UDP

传输层 传输层是OSI模型的第四层&#xff0c;主要负责端到端的数据传输&#xff0c;确保数据可靠、有> 序地从源设备传送到目标设备。其主要功能包括&#xff1a; 端到端通信&#xff1a;在源和目标设备之间建立连接&#xff0c;确保数据准确传输。数据分段与重组&#xff1…...