这是不一样的svg图像优化哦。-可优化也可转换为组件

news2024/11/14 3:38:36

田间的风吹老了岁月,老舍笔下的茶馆写的是近代史,真的写尽了当时的苦态,可能现在的地铁写的是现代史吧。时光飞逝,很快就工作两三年了。昨天做项目的时候,引入svg图像转换为组件的时候,觉得很麻烦,自己手动转换,效率低,而且无脑,关键还不能直接用,有时候UI切的svg的图是没办法直接转为组件的,还要手动修改,这让我这个底层打工仔很生气。一怒之下,写了个插件,进行转换。然后就篇文章分享一下给大家,同时大家也可以直接使用。

介绍

在现代Web开发中,SVG因其无损缩放和丰富的交互性而受到广泛欢迎。然而,手动将SVG文件转换为React组件不仅耗时,还容易出错。然后我就开发了个工具-wsksvgwsksvg它不仅能过,实现对svg的优化,包括png,jpg图片的优化,还能够自动将SVG文件转换为格式化的无状态React组件或Vue组件支持单文件处理,也支持批量处理,只需要一个安装和一条指令,大大提高开发效率,增加底层打工人的摸鱼的时间。

功能和特点

以下是其主要功能和特点:

1.SVG 优化:

使用 svgo 进行 SVG 文件的优化,包括调整颜色、移除不必要的属性等。
根据 --vue 或 --react 选项,生成 Vue 或 React 组件。

2.组件生成:

Vue 组件:将 SVG 转换为 Vue 单文件组件(.vue)。
React 组件:将 SVG 转换为 React 组件(.tsx)。

3.图像优化:

支持 PNG、JPG 和 JPEG 格式图像的优化。
使用 sharp 进行图像尺寸调整和优化。

4.输入输出处理:

支持处理单个文件或目录下的所有 SVG、PNG、JPG、JPEG 文件。
输出路径可以指定,也可以不指定,默认在输入路径相同目录下生成。

特点

  • 灵活配置:根据选项生成 Vue 或 React 组件,或仅优化 SVG 文件。
  • 自动路径处理:支持处理文件和目录,并自动创建输出目录。
  • 增强 SVG 功能:保留 SVG 原始颜色和尺寸,移除不必要的属性。
  • 详细日志:打印原始和优化后的文件大小,帮助用户了解优化效果。
  • 错误处理:对不支持的文件类型和处理错误有明确的错误提示。

这个工具为开发人员提供了便捷的方式来优化图像并生成组件,适用于需要处理大量 SVG 文件和图像资源的项目。

使用说明

1.安装

npm install -g wsksvg

2.使用列子

  wsksvg audio-file-raw.svg 
  wsksvg audio-file-raw.jpg
  wsksvg audio-file-raw.png
  wsksvg ./rawSvg
  wsksvg ./rawSvg ./test  //默认优化
  wsksvg ./rawSvg ./testVue --vue  //生成vue组件
  wsksvg ./rawSvg ./testReact --react //生成react 组件
  wsksvg  ./raw  //支持模糊匹配文件名称
  ./rawSvg 输入文件路径  ./test 输出文件路径

灵感来源

做公司项目的时候,不同项目之间总是使用相同的图标,或者只是颜色不同的图标,还有大小不一样的图标,因为不同项目间的,没办法共用,我就开始写个图标组件库,动态的改变图标的颜色,使用svg图片是比较合适的,符合我的项目需求,但是单纯的svg图标无法实现动态图标,那要转化为组件,我用的是react,那我要转化为React组件。刚开始不以为然,命名传参,返回svg图像,但UI切的SVG图,并不什么时候都能用够直接使用的,需要处理,因为React组件正常使用,需要手动修改。
在这里插入图片描述

那时候就开始思考,能不能通过工具进行处理,然后进行百度,还别说真的可以,有现成的插件的,可以直接生成,但是插件它只能生成React的组件, 不能生成Vue的组件,那就不能在不同框架下进行使用,有时候我也只想对图片进行优化,有些图标不需要改变颜色,尺寸,也不需要点击交互,单纯的优化。那它就不满足我的需求了。就开始尝试自己写一个。

实现过程

SVG 转React组件

寻找解决方案,发现svgr插件能够进行处理,那就自己写个文件进行处理,首先明白自己的需求,我想把一个文件夹下面的所有的SVG图片,都编译成react组件,那就是读取一个文件夹下的所有svg,那就要用到node fs 实现文件的读取,
然后进行格式转化通过–这个插件来处理,然后查看这个插件的官网,进行编译,然后写到另外一个文件下,汇总到index.ts文件中,共我导出使用。

import { transform } from '@svgr/core';
import { resolve, dirname, extname, basename } from 'path';
import { fileURLToPath } from 'url';
import fs from 'fs';
import camelCase from 'camelcase';
import { optimize } from 'svgo';
import svgoConfig from '../svgo.config.js';
import svgoRawConfig from '../svgo.raw.config.js';

const __dirname = dirname(fileURLToPath(import.meta.url));

const entryDir = resolve(__dirname, '../rawSvg');
const outDir = resolve(__dirname, '../src/ReactIcons');

// Ensure output directory exists
if (!fs.existsSync(outDir)) {
  fs.mkdirSync(outDir, { recursive: true });
}

// Read all SVG files from the input directory
const files = fs.readdirSync(entryDir, 'utf-8');
const indexFileName = 'index.ts';
const prefix = '';
const suffix = '';

// Process SVG files
const batches = files.filter(f => extname(f) === '.svg').map(async file => {
  try {
    const svgFileName = basename(file, '.svg');
    const componentName = `${prefix}${camelCase(svgFileName, { pascalCase: true })}${suffix}`;
    const reactFileName = `${componentName}.tsx`;
    const svgContent = fs.readFileSync(resolve(entryDir, file), 'utf-8');

    // Choose appropriate SVGO configuration
    const config = file.includes('-raw.svg') ? svgoRawConfig : svgoConfig;
    const result = optimize(svgContent, config);

    // Transform SVG to React component
    const jsxCode = await transform(result.data, {
      plugins: ['@svgr/plugin-jsx', '@svgr/plugin-prettier'],
      icon: true,
      typescript: true,
    }, {
      componentName: componentName,
    });

    // Write transformed SVG to a file
    fs.writeFileSync(resolve(outDir, reactFileName), jsxCode, 'utf-8');
    return { fileName: reactFileName, componentName };
  } catch (error) {
    console.error(`Error processing file ${file}:`, error);
    throw error;
  }
});

// Generate index file with exports
const arr = await Promise.all(batches);
const indexFileContent = arr.map(a => `export { default as ${a.componentName} } from './${a.componentName}';`).join('\n');
fs.writeFileSync(resolve(outDir, indexFileName), indexFileContent, 'utf-8');

console.log('SVG to React components conversion completed successfully.');

React都转了也不差Vue的

思考React的都能实现,React用的是jsx语法,Vue3支持,但Vue2不支持,Vue的语法,不就是模板语法嘛,编写模板语法,然后在把SVG写到模板语法中。

import { optimize } from 'svgo';
import fs from 'fs';
import path from 'path';
import camelCase from 'camelcase';
import { fileURLToPath } from 'url';

import svgoConfig from '../svgo.config.js';
import svgoRawConfig from '../svgo.raw.config.js';

// 获取 __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const entryDir = path.resolve(__dirname, '../rawSvg');
const outDir = path.resolve(__dirname, '../src/VueIcons');

// 确保输出目录存在
if (!fs.existsSync(outDir)) {
  fs.mkdirSync(outDir, { recursive: true });
}

// 读取所有 SVG 文件
const files = fs.readdirSync(entryDir, 'utf-8');

// 处理 SVG 文件
const batches = files.filter(f => path.extname(f) === '.svg').map(async file => {
  try {
    const svgFileName = path.basename(file, '.svg');
    const componentName = camelCase(svgFileName, { pascalCase: true });
    const vueFileName = `${componentName}.vue`;
    const svgContent = fs.readFileSync(path.resolve(entryDir, file), 'utf-8');

    // 选择适当的 SVGO 配置
    const config = file.includes('-raw.svg') ? svgoRawConfig : svgoConfig;
    const result = optimize(svgContent, config);

    // 创建 Vue 组件模板
    const vueCode = `
<template>
  <svg xmlns="http://www.w3.org/2000/svg" v-html="icon" ></svg>
</template>

<script setup>

const icon = \`${result.data}\`;
</script>

<style scoped>
svg {
  width: 1em;
  height: 1em;
}
</style>
    `;
    // 将 Vue 组件写入文件
    fs.writeFileSync(path.resolve(outDir, vueFileName), vueCode, 'utf-8');
    return { fileName: vueFileName, componentName };
  } catch (error) {
    console.error(`Error processing file ${file}:`, error);
    throw error;
  }
});
// 生成 index.ts 文件
const arr = await Promise.all(batches);
const indexFileContent = arr.map(a => `export { default as ${a.componentName} } from './${a.componentName}.vue';`).join('\n');
fs.writeFileSync(path.resolve(outDir, 'index.ts'), indexFileContent, 'utf-8');

console.log('SVG to Vue components conversion completed successfully.');


只想优化SVG图像

有时候我又在想,不是很想转化,这个插件能够进行优化,在转化,那我想只是优化一下,输出的还是svg图片,查看文档,发现配置,进行配置优化,输出。当然一些svg是不需要改变颜色的,写死的,那这个优化配置就不能一样了。就进行判断,通过文件命名吧。

import { optimize } from 'svgo';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';

// 获取 __dirname
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const entryDir = path.resolve(__dirname, '../rawSvg'); // 输入目录
const outDir = path.resolve(__dirname, '../src/optimizedSvg'); // 输出目录

// 确保输出目录存在
if (!fs.existsSync(outDir)) {
  fs.mkdirSync(outDir, { recursive: true });
}

// 读取所有 SVG 文件
const files = fs.readdirSync(entryDir, 'utf-8');

// 处理 SVG 文件
const processFiles = files.filter(f => path.extname(f) === '.svg').map(async file => {
  try {
    const filePath = path.resolve(entryDir, file);
    const svgContent = fs.readFileSync(filePath, 'utf-8');

    // 优化 SVG 内容
    const result = optimize(svgContent, {
      multipass: true, // 多次优化
      // 其他配置选项可以在这里添加
    });

    // 写入优化后的 SVG 文件
    const outputPath = path.resolve(outDir, file);
    fs.writeFileSync(outputPath, result.data, 'utf-8');
    console.log(`Optimized ${file}`);
  } catch (error) {
    console.error(`Error processing file ${file}:`, error);
  }
});

// 等待所有文件处理完成
await Promise.all(processFiles);

console.log('SVG optimization completed successfully.');

进行自动化实现(写个插件或者服务)

写了三个脚本,文件,但是只能在这个项目中使用,还是写个服务吧,用户上传svg文件,在页面中进行选择,是优化,还是生成react组件代码还是Vue的一点复制,或者下载文件,那就完美了,部署在github的静态管理中,我就能够随时用了(我觉得我这个想法挺好),但是写一个上传需要一个服务,写一个服务简单,但是我的服务器快到期了,没钱续费了(年年打工,年年穷,越干前端,越是穷,只能解决温饱,不能致富啊),再者我想分享一下这个插件,觉得挺不错的,不敢给网友们用,主要担心有些人拿它做测试把我服务器搞溃,本来就不富裕的人,变得更穷了。那就写个npm脚本吧,通过运行脚本执行,方便你我,想用的都可以用,方便你我。
在这里插入图片描述

规范输入指令化

之前是通过不同的指令执行不同的js脚本文件,文件路径都是写死的,生成的react,跟vue也是写死的,那样肯定不行,不灵活,而且不方便,那就让用户输入吧,输入要转化的文件,或者文件夹,路径跟名称,还有输出的路径跟文件夹名字,同时也要指定生成React组件,还是Vue组件,还是只进行优化。**然后在测试过程中,觉得,我只想输入个文件名字或者路径,跟给个默认的执行比较好,这样体验感才会上去,那就默认如果没有给一个新的文件夹,在同一个文件下就进行一个.copy的扩展,如果没有指定是生成组件,还是优化,那就默认进行优化。**这样的一个过程。体验感不错,然后就这样规定。

Options:
  --vue           Generate Vue components from SVG files.
  --react         Generate React components from SVG files.
  -h, --help      Display this help message.
Examples:
  wsksvg ./rawSvg
  wsksvg ./rawSvg ./test
  wsksvg ./rawSvg ./testVue --vue
  wsksvg ./rawSvg ./testReact --react

  ./rawSvg Input file path  ./test Output file path

懒得拼全名字模糊输入

输入路径的名称的时候,看到哪里只有这一个文件名,懒得打全名称,能不能进行模糊处理,同时也可以指定了摸个命名一样的进行处理,觉得这个想法不错,就进行了处理一下。效果不错。

   wsksvg raw 也能够匹配到    wsksvg rawSvg.svg

svg都能优化,png,跟jpg也做一下优化吧

看到我的项目上不仅有svg图片,也有png跟jpg,能不能也把它们一起优化算了。然后引入了sharp 插件,emm,感觉效果可以,这下一个文件下的图片都进行了优化。哈哈哈哈哈哈哈,体验感也上去了,静态文件小了,加载图片的速度也加快了。

sharp 是一个用于图像处理的高性能 Node.js 库。它提供了广泛的功能来处理和优化图像,特别适合在服务器端进行图像操作。

// 处理 PNG 或 JPG 文件
async function processImageFile(filePath: string, output: string) {
  const fileName = path.basename(filePath, path.extname(filePath));
  const fileDir = path.dirname(filePath);
  const originalBuffer = fs.readFileSync(filePath);

  // 计算原始文件大小
  const originalSize = Buffer.byteLength(originalBuffer);

  // 生成输出目录路径
  const outputDir = output ? path.resolve(process.cwd(), output) : fileDir;
  ensureDirectoryExists(outputDir); // 确保输出目录存在

  // 生成输出文件路径
  const extname = path.extname(filePath);
  let outputPath = path.resolve(outputDir, `${fileName}${extname}`);

  // 检查输出路径是否已存在
  if (fs.existsSync(outputPath)) {
    outputPath = path.resolve(outputDir, `${fileName}.copy${extname}`);
  }

  // 计算优化后的文件缓冲区
  const optimizedBuffer = await sharp(originalBuffer)
    .resize({ withoutEnlargement: true })  // 根据需要调整大小
    .toBuffer();

  // 写入优化后的文件
  fs.writeFileSync(outputPath, optimizedBuffer);

  // 打印优化信息
  const newSize = Buffer.byteLength(optimizedBuffer);
  console.log(`Optimized ${path.basename(filePath)} -> ${path.basename(outputPath)}`);
  console.log(`Original Size: ${originalSize} bytes`);
  console.log(`Optimized Size: ${newSize} bytes`);
}

输出优化提示

用户输入路径,不知道会是那个,那就做个优化,提示一下它吧输出一下目前找的路径,然后发现我插件进行了优化了图片,但是优化了多少却不知道,还要最后去看文件的属性里面的文件大小,那就输出优化前后的文件大小,让用户知道这个插件做的优化,优化的图片数量。
在这里插入图片描述

SVG跟组件采用不同过的优化策略

为什么会这样呢,因为如果采用同一种优化策略,SVG图像无法显示
SVG优化

// SVGO 配置
const svgoConfig = {
  js2svg: {
    indent: 2,
    pretty: true,
  },
  plugins: [
    {
      name: 'preset-default',
      params: {
        overrides: {
          removeViewBox: false, // 保持 viewBox
          inlineStyles: {
            onlyMatchedOnce: false,
          },
        },
      },
    },
    {
      name: 'convertStyleToAttrs',
      params: {
        onlyMatchedOnce: false,
      },
    },
    {
      name: 'removeAttrs',
      params: {
        attrs: ['svg:style'], // 可选:移除内联样式,但保留 width 和 height
      },
    },
    {
      name: 'addAttributesToSVGElement',
      params: {
        attributes: [{
          width: '1em',
          height: '1em',
          'aria-hidden': true,
          focusable: 'false',
        }]
      }
    }
  ],
};

组件优化SVG

const svgoComConfig = {
  js2svg: {
    indent: 2,
    pretty: true,
  },
  plugins: [
    {
      name: 'preset-default',
      params: {
        overrides: {
          removeViewBox: false,
          inlineStyles: {
            onlyMatchedOnce: false,
          },
        },
      },
    },
    'removeXMLNS',
    'convertStyleToAttrs',
    {
      name: 'convertColors',
      params: {
        attrs: ['svg:style'], // 可选:移除内联样式,但保留 width 和 height
      },
    },
    {
      name: 'removeAttrs',
      params: { attrs: ['opacity'] }, // 移除不需要的 opacity 属性,但保留 width 和 height
    },
    {
      name: 'addAttributesToSVGElement',
      params: {
        attributes: [{
          'aria-hidden': true,
          focusable: 'false',
          // 不设置 width 和 height,以保持原始大小
        }]
      }
    }
  ],
};

也许不同的需求不同,后面会进行一个扩展,扩展成可以自定义优化文件。 这是svgo 优化配置文件。

总是报错,那就弄个帮助说明

不小心输入出错了,提示报错,感觉如果没有个帮助说明不太好,别人不知道怎么用,就在做一下优化提示,给出一下例子。让用户知道怎么用。

在这里插入图片描述

进行测试

项目中进行使用
执行前
在这里插入图片描述

执行后
在这里插入图片描述

如果输出的文件中不存在该文件名称,则不加copy,如果存在则在中间加后缀.copy
在这里插入图片描述

效果

这是批量处理的效果,以及输出的提示,还有优化的大小
优化前后的大小对比(特地找个大量的图片来过测试)
优化前的总大小
在这里插入图片描述

优化后的总大小
在这里插入图片描述

优化了将近一半

在这里插入图片描述

优化前后的图像对比
在这里插入图片描述
是没啥差别点的。

生成React组件

在这里插入图片描述
在这里插入图片描述
文件大小
在这里插入图片描述

生成Vue组件
在这里插入图片描述
在这里插入图片描述
文件大小
在这里插入图片描述

可以看到都比之前少了60%总体上!!!!

最后

其实开发一个插件并不能,很多事情都可以进行自动化的进行处理,这些没什么技术含量的工作,刚开始我也是手动的将SVG图片转为React组件,反正也就那样,无所事事,没觉得有什么,但有时候思考一下,能不能通过工具实现这种无聊的工作呢,而且自己去尝试,去尝试的过程中,会引发自己的大量思考,从而它也是一种提升。 有人肯定会说,能实现就行了,没必要去思考那么多,有那时间还不如去摸鱼。我也想说,哈哈哈,不过真的停下来思考一下,实现过程并不难,这个插件我一天不到就实现了,而且能解决项目这种转化的问题,也剩下更多的摸鱼时间,也更多的时间去做自己喜欢做的事情,反正总工时不能变,打工人倔强。

如果你也觉得这个插件不错的化,帮助到你了,可以给个点赞,给我的github点个Star。

github地址:https://github.com/wskang12138/wsk-icons

总结

将SVG图像转换为组件可以显著提高开发效率,但手动处理这些转换往往耗时且容易出错。为了简化这一过程,wsksvg工具它不仅能够优化SVG、PNG、JPG图片,还可以自动将SVG文件转换为格式化的无状态React或Vue组件。通过这个工具,用户可以轻松实现单文件或批量处理,减少了手动转换的繁琐步骤,提高了工作效率,同时也支持根据需求选择不同的处理方式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2090518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2.2 语言处理程序基础

以编译方式翻译C/C源程序的过程中&#xff0c;类型检查在&#xff08; &#xff09;阶段处理。 A. 词法分析 B. 语义分析 C. 语法分析 D. 目标代码生成 正确答案是 B。 解析 本题考查的是编译器工作过程。 A选项词法分析阶段处理的错误&#xff1a;非法字符、单词拼写错误等。与…

《王者荣耀》游戏玩法与部分机制分析

目录 游戏机制 MOBA核心玩法 匹配机制 游戏模式 隐藏分机制 游戏规则 总结 王者荣耀的ELO匹配机制是如何具体工作的&#xff1f; 王者荣耀中隐藏分机制的详细规则是什么&#xff1f;&#xff08;难绷&#xff01;&#xff09; 王者荣耀边境突围和五军对决模式的具体玩…

解释:有序树是什么意思?

目录 有序树的特性&#xff1a; 例子&#xff1a; 总结 &#x1f31f; 嗨&#xff0c;我是命运之光&#xff01; &#x1f30d; 2024&#xff0c;每日百字&#xff0c;记录时光&#xff0c;感谢有你一路同行。 &#x1f680; 携手启航&#xff0c;探索未知&#xff0c;激发…

STM32基于HAL库使用串口+DMA 不定长接收数据 学习记录

我这些博客都只是记录一下自己学习的内容&#xff0c;以及记录一些思考过的问题和疑惑的东西 这里的代码借鉴了一位博主的博客 地址&#xff1a;[] 这里cubemx串口基础配置部分参考这一篇博客 &#xff08;只配置了串口中断接收和printf重定向&#xff09; 这一篇博客我们需要开…

C++编程:理解左值(lvalue)和右值(rvalue)

C 值的分类(Value Categories) 目录 1 概述 2 主要分类 1.1 左值(lvalue) 1.1.1 左值详情 1.1.2 左值属性 1.2 纯右值(prvalue) 1.2.1 纯右值详情 1.2.2 纯右值属性 1.3 将逝值(xvalue) 1.3.1 将逝值详情 1.3.2 将逝值属性 3 混合分类 3.1 泛型左值…

Day51 | 117. 软件构建(拓扑排序)47. 参加科学大会 dijkstra(朴素版)

语言 117. 软件构建 117. 软件构建 题目 题目描述 某个大型软件项目的构建系统拥有 N 个文件&#xff0c;文件编号从 0 到 N - 1&#xff0c;在这些文件中&#xff0c;某些文件依赖于其他文件的内容&#xff0c;这意味着如果文件 A 依赖于文件 B&#xff0c;则必须在处理…

【STM32】通用定时器TIM(时钟源选择与更新中断)

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 通用定时器简介 定时器时钟使能 选择时基单元时钟源 内部时钟源 外部时钟源 时基单元初始化 更新中断使能 定时器使能 定时器中断代码 Timer.h Timer.c 获取计数值 TIM(Time…

【王树森】RNN模型与NLP应用(7/9):机器翻译与Seq2Seq模型(个人向笔记)

Machine Translation Data 做机器学习任务的第一步都是处理数据&#xff0c;我们首先需要准备机器翻译的数据。由于我们是学习用途&#xff0c;因此拿一个小规模数据集即可&#xff1a;http://www.manythings.org/anki/下面的数据集中&#xff1a;一个英语句子对应多个德语句子…

Spring MVC执行流程

整体流程&#xff1a; 用户向前端控制器发送请求前端控制器接收到请求后调用处理映射器处理器映射器找到具体的处理器&#xff0c;生成处理器对象以及处理器拦截器&#xff0c;再一起返回给前端控制器然后前端控制器调用处理器适配器处理器适配器调用具体的处理器处理器适配器…

element plus el-upload上传组件,自动上传,记录解决:本地报404,文件找不到问题

问题&#xff1a; 解决问题&#xff1a; 重点是&#xff1a;加入action"#"和:http-request"uploadHttpRequest" <el-uploadv-loading"isLoading"ref"upload"v-model"fileList":multiple"multiple"action&quo…

《PCI Express体系结构导读》随记 —— 第II篇 第7章 PCIe总线的数据链路层与物理层(1)

前言中曾提到&#xff1a;本章重点介绍PCI Express总线的数据链路层与物理层。 PCIe总线的数据链路层处于事务层和物理层之间&#xff0c;主要功能是保证来自事务层的TLP在PCIe链路中的正确传递&#xff0c;为此数据链路层定义了一系列数据链路层报文&#xff0c;即DLLP。数据链…

AI实践与学习8-AI Agent Workflow助力解题和验证答案置信度

背景 之前在试着提高解题正确率&#xff0c;目标100%&#xff0c;发现外部知识不足仅依靠大模型的话比较困难。而试题人工生产成本巨大。 本质因为大模型生成内容会有幻觉特点&#xff0c;也就是说解答的试题正确性不太好评判&#xff0c;直接解答试题生产场景不太可控。 后…

市场纷乱中,沃尔沃坚守长期主义之道,用“P1+P4”解决用户痛点3A品质,插混王者——沃尔沃插混让性能成为插混必要条件

“造车就像西天取经&#xff0c;明确的方向、实现目标的能力&#xff0c;内心的坚持缺一不可”,本届成都国际车展上&#xff0c;来自沃尔沃汽车集团全球高级副总裁袁小林的一句话可谓是振聋发聩&#xff0c;向沉迷玩转“流量密码”的车企&#xff0c;向因各种噱头而迷茫的用户发…

RISC-V全志D1sCVBS套件

此开发板的任何问题都可以在我们的论坛交流讨论 https://forums.100ask.net/c/10-category/75-category/75 硬件简述 D1s主板 主板如下&#xff1a; D1s板载功能 板载功能有 XR829 WIFI蓝牙模组芯片&#xff0c;Bluetooth支持标准蓝牙与 低功耗蓝牙&#xff0c;Wifi 支持…

论被动元数据的弊端,以及主动元数据的技术优势

元数据是企业数据生态系统中不可或缺的组成部分&#xff0c;核心在于为数据本身提供完整的描述性信息&#xff0c;包括数据来源、数据结构、语义含义、物理位置、所有权归属、创建时间、流转路径等关键要素&#xff0c;是企业理解、开发、消费和应用数据的基石。 元数据管理&a…

毕设创新点之一:基于GD32/STM32的AI模型部署-github库

将AI模型成功部署到边缘MCU中&#xff0c;常常受限于MCU的计算峰值和内存峰值的限制&#xff0c;部署较为困难&#xff0c;目前有一个将AI算法MCU部署到GD32系列MCU中的宝藏的开源库。 项目网址&#xff1a;HomiKetalys/gd32ai-modelzoo: Provide deployable deep learning mo…

springweb获取请求数据、spring中拦截器

SpringWeb获取请求数据 springWeb支持多种类型的请求参数进行封装 1、使用HttpServletRequest对象接收 PostMapping(path "/login")//post请求//spring自动注入public String login(HttpServletRequest request){ System.out.println(request.getParameter("…

若依脚手架 创建一个系统 his医院信息管理系统

一、创建his-medicine模块 0) 在创建好的若依后端项目中创建一个maven模块his-medicine 1&#xff09;his模块的整合步骤 ①&#xff09;his的依赖 这个是若依项目所有系统模块都需要添加的依赖&#xff0c;domain和controller继承的类就在这里面。 <!-- 通用工具--><…

【位置编码】【Positional Encoding】直观理解位置编码!把位置编码想象成秒针!

【位置编码】【Positional Encoding】直观理解位置编码&#xff01;把位置编码想象成秒针&#xff01; 你们有没有好奇过为啥位置编码非得长成这样&#xff1a; P E ( p o s , 2 i ) s i n ( p o s 1000 0 2 i / d m o d e l ) P E ( p o s , 2 i 1 ) c o s ( p o s 1000 …

基于yolov8的手势识别0-9检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的手势识别0-9检测系统是一个利用深度学习技术&#xff0c;特别是YOLOv8算法&#xff0c;实现对手势&#xff08;0至9的数字手势&#xff09;进行快速、准确识别的系统。YOLOv8以其高效的性能和准确性&#xff0c;在实时性要求较高的手势识别领域表现出…