【unity数据持久化】XML数据管理器知识点

news2024/10/7 14:28:25

在这里插入图片描述


👨‍💻个人主页:@元宇宙-秩沅

👨‍💻 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅!

👨‍💻 本文由 秩沅 原创

👨‍💻 收录于专栏:Unity基础实战

🅰️



文章目录

    • 🅰️
    • 前言
        • XML是什么
        • 和游戏存储的关系
    • 🎶(==A==) XML文件格式
    • 🎶(==B==) XML基本规则
    • 🎶(==C==) XML属性
    • 🎶(==D==) 读取XML文件(c#)
    • 🎶(==E==) 读取XML文件中的信息(c#)
    • 🎶(==F==) 存储XML文件中的信息(c#)
    • 🎶(==G==) 修改XML文件中的信息(c#)
    • 🎶(==s==) XML 练习
          • XML编写练习
          • 读取练习
          • 存取练习
    • 🅰️


前言

XML是什么

XML(Extensible Markup Language)是一种类似于 HTML,但是没有使用预定义标记的语言。因此,可以根据自己的设计需求定义专属的标记。这是一种强大将数据存储在一个可以存储、搜索和共享的格式中的方法。最重要的是,因为 XML 的基本格式是标准化的,如果你在本地或互联网上跨系统或平台共享或传输 XML,由于标准化的 XML 语法,接收者仍然可以解析数据。

  • 全称可拓展标记语言extentsible markup language
  • XML是国际通用的
  • 它是被设计用来传输和存储数据的一种文本特殊格式

和游戏存储的关系

  • 游戏数据按照XML的格式标准——>存储在XML文档中
  • 再将XML文档存储在硬盘上或者传输给远端——达到数据持久化

一种存储和传输数据的选择
一种配置数据的方法

在这里插入图片描述


🎶(A XML文件格式


特点: 是一种树形结构

在这里插入图片描述

  • 注释的格式:——!–在这里写注释–

_________在这里插入图片描述

  • 固定的格式——?xml version =“1.0” encoding = “UTF-8”?
    在这里插入图片描述
  • UTF - 8是什么意思
    和ASCII码一样它也是一种编码格式只不过ASCII码是最原始的编码格式

世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码.电子邮件常常出现乱码?就是因为发信人和收信人使用的编码方式不一样。

ASCII,Unicode和UTF-8终于找到一个能完全搞清楚的文章了


🎶(B XML基本规则


符号含义
&lt — <小于
&gt — >大于
&amp — &
&apos — ’单引号
&quot — "引号

注意:

1.每个元素都必须有关闭标签
2.元素命名规则基本遵照C#中变量名命名规则
3.XML标签要注意大小写
4.XML文档必须有根元素

在这里插入图片描述


🎶(C XML属性


  • 属性的特点

属性就是在元素标签后面空格 添加的内容
注意: 属性必须用引号包裹 单引号双引号都可以

  • 属性写法

    元素节点 —————————————> 属性
    

    作用都一样
    在这里插入图片描述

  • 格式验证方法

菜鸟教程XML 格式验证器

  • 练习

当出现没有变量名的数据时 就用变量类型名命名
在这里插入图片描述


🎶(D 读取XML文件(c#)


  • Xml文件存放位置

  • 1.只读不写的XML文件可以放在
    Resources或者StreamingAssets 文件夹下

  • 2.动态存储的XML文件放在
    Application.persistentDataPath 路径下

C#读取XML的方法有3种

  • 1.XmlDocument (把数据加载到内存中,使用XmlDocument类读取是较方便最容易理解和操作的方法)
  • 2.XmlTextReader (以流形式加载,内存占用更少,但是是单向只读,使用不是特别方便,除非有特殊需求,否则不会使用)
  • 3.Linq

XmlDocument

XmlDocument xml = new XmlDocument();

  • 1.xml文件名加载——存放在Resorces文件夹下的xml文件加载处理
        //为TextAsset  Resorces文件夹下的文本类
        TextAsset asset = Resources.Load<TextAsset>("xml文件名");
        print(asset.text);
        
        //加载为xml对象
        xml.LoadXml(asset.text);
  • 2.通过xml文件的路径加载——存放在StreamingAssets 文件夹下的xml文件加载处理
xml.Load(Application.streamingAssetsPath + "/xml文件名.xml");
//streamingAssetsPath 文件夹只读(移动端)pc(可读可写)

注意: 为什么不读Resource文件夹的路径,因为打包后它被压缩了读不到


🎶(E 读取XML文件中的信息(c#)


XmlDocument xml = new XmlDocument();

1.相关类:

  • XmlNode 单个节点信息类
  • XmlNodeList 多个节点信息类
  • XmlDocument 用于创建节点 存储文件
  • XmlDeclaration 用于添加版本信息
  • XmlElement 节点类

2.获取xml当中的根节点:

  • XmlNode root = xml.SelectSingleNode(“根节点名”);

3.获取下面的子节点:

  • XmlNode nodeName = root.SelectSingleNode(“name”);

4.获取节点包裹的元素信息

  • nodeName.InnerText

5.获取节点属性信息

  • XmlNode nodeItem = root.SelectSingleNode(“Item”);
  • ①nodeItem.Attributes[“属性名”].Value
  • ②nodeItem.Attributes.GetNamedItem(“属性名”).Value

6.获取 一个节点下的同名节点的方法

为什么会有同名?
因为当出现没有变量名的数据时 就用变量类型名命名在这里插入图片描述

  • XmlNode nodeListInt = root.SelectSingleNode(“ListInt”);
  • XmlNodeList intList = nodeListInt.SelectNodes(“int”);

7.得到之后遍历

  • 迭代器遍历 foreach (XmlNode node in intList )
  • for循环遍历 for (int i = 0; i < intList .Count; i++)

8.得到子节点的子节点

  • 写法一
    XmlNode node = Xml.SelectSingleNode(“Root”).SelectSingleNode(“name”);
  • 写法二
    XmlNode node = Xml.SelectSingleNode(“Root/name”);


🎶(F 存储XML文件中的信息(c#)


  • 特殊文件夹读写性回顾

1.Resources 可读 不可写 打包后找不到
2.Application.streamingAssetsPath 可读 PC端可写 找得到
3.Application.dataPath 打包后找不到
4.Application.persistentDataPath 可读可写找得到

存储xml文件 在Unity中一定是使用各平台都可读可写可找到的路径


1.相关类:

  • XmlNode 单个节点信息类
  • XmlNodeList 多个节点信息类
  • XmlDocument 用于创建节点 存储文件
  • XmlDeclaration 用于添加版本信息
  • XmlElement 节点类

通过代码API创建XML信息,不需要手动编写的流程

  • 0.及记录存储文件夹信息的路径
  
   string path = Application.persistentDataPath + "/要创建的文件夹名.xml";
  
  • 1.创建文本对象

      XmlDocument xml = new XmlDocument();
    
  • 2.添加固定版本信息

//相当于就是创建<?xml version="1.0" encoding="UTF-8"?>这句

  XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
 
//创建完成过后 要添加进入 文本对象中

  xml.AppendChild(xmlDec);
  • 3. 添加根节点
  XmlElement root = xml.CreateElement("Root");
  
  xml.AppendChild(root);

  • 4.为根节点添加子节点
     XmlElement name = xml.CreateElement("name");
     
        name.InnerText = "孙悟空";
        root.AppendChild(name);
        
    XmlElement age = xml.CreateElement("age");
    
        atk.InnerText = "10";
        root.AppendChild(age);
        
    XmlElement listInt = xml.CreateElement("listInt");
       //子节点里面加子节点组
        for (int i = 1; i <= 3; i++)
        {
            XmlElement childNode = xml.CreateElement("int");
            childNode.InnerText = i.ToString();
            listInt.AppendChild(childNode);
        }
        
        root.AppendChild(listInt);

  • 5.添加属性
   XmlElement itemList = xml.CreateElement("itemList");
        for (int i = 1; i <= 3; i++)
        {
            XmlElement childNode = xml.CreateElement("Item");
            //添加属性
            childNode.SetAttribute("id", i.ToString());
            childNode.SetAttribute("num", (i * 10).ToString());
            itemList.AppendChild(childNode);
        }
        root.AppendChild(itemList);
  • 6.保存

         xml.Save(path);
    

🎶(G 修改XML文件中的信息(c#)


1.相关类:

  • XmlNode 单个节点信息类
  • XmlNodeList 多个节点信息类
  • XmlDocument 用于创建节点 存储文件
  • XmlDeclaration 用于添加版本信息
  • XmlElement 节点类

string path = Application.persistentDataPath + “/要创建的文件夹名.xml”;


  • 1.判断是否存在文件

File.Exists(path)

  • 2.加载XML文件API

newXml.Load(path);

【newXml -> XmlDocument类】

  • 3.创建节点

newXml.CreateElement(“节点名字”);

  • 5.增加子节点

root.AppendChild(node)

  • 6.移除子节点

root.RemoveChild(node);
【root -> XmlElemen节点类】

   if( File.Exists(path) )
        {
            //加载      
            newXml.Load(path);
            
            //移除
            XmlNode node;
            node = newXml.SelectSingleNode("Root/atk");
            
            //得到父节点
            
            XmlNode root2 = newXml.SelectSingleNode("Root");
            //移除子节点
            
            root2.RemoveChild(node);

            //添加节点
            
            XmlElement speed = newXml.CreateElement("moveSpeed");
            speed.InnerText = "20";
            root2.AppendChild(speed);
            
            //记得存
            
            newXml.Save(path);
        }

🎶(s XML 练习


XML编写练习

当出现没有变量名的数据时 就用变量类型名命名
在这里插入图片描述

读取练习
//将一个和PlayerInfo相同信息的XML文件的值读取出来赋给另一个对象
public class Item
{
    public int id;
    public int num;
}

public class PlayerInfo
{
    public string name;
    public int atk;
    public int def;
    public float moveSpeed;
    public float roundSpeed;
    public Item weapon;
    public List<int> listInt;
    public List<Item> itemList;
    public Dictionary<int, Item> itemDic;

    public void LoadData(string fileName)
    {
        //加载XML文件信息
        XmlDocument xml = new XmlDocument();
        //加载
        xml.Load(Application.streamingAssetsPath + "/" + fileName + ".xml");

        //从文件中加载出具体的数据
        //加载根节点 才能加载后面的内容
        XmlNode playerInfo = xml.SelectSingleNode("PlayerInfo");
        //通过根节点 去加载具体的信息
        this.name = playerInfo.SelectSingleNode("name").InnerText;
        this.atk = int.Parse(playerInfo.SelectSingleNode("atk").InnerText);
        this.def = int.Parse(playerInfo.SelectSingleNode("def").InnerText);
        this.moveSpeed = float.Parse(playerInfo.SelectSingleNode("moveSpeed").InnerText);
        this.roundSpeed = float.Parse(playerInfo.SelectSingleNode("roundSpeed").InnerText);

        XmlNode weaponNode = playerInfo.SelectSingleNode("weapon");
        this.weapon = new Item();
        this.weapon.id = int.Parse(weaponNode.SelectSingleNode("id").InnerText);
        this.weapon.num = int.Parse(weaponNode.SelectSingleNode("num").InnerText);

        XmlNode listIntNode = playerInfo.SelectSingleNode("listInt");
        XmlNodeList intList = listIntNode.SelectNodes("int");
        this.listInt = new List<int>();
        for (int i = 0; i < intList.Count; i++)
        {
            this.listInt.Add(int.Parse(intList[i].InnerText));
        }

        XmlNode itemList = playerInfo.SelectSingleNode("itemList");
        XmlNodeList items = itemList.SelectNodes("Item");
        this.itemList = new List<Item>();
        foreach (XmlNode item in items)
        {
            Item item2 = new Item();
            item2.id = int.Parse(item.Attributes["id"].Value);
            item2.num = int.Parse(item.Attributes["num"].Value);
            this.itemList.Add(item2);
        }

        XmlNode itemDic = playerInfo.SelectSingleNode("itemDic");
        XmlNodeList keyInt = itemDic.SelectNodes("int");
        XmlNodeList valueItem = itemDic.SelectNodes("Item");

        this.itemDic = new Dictionary<int, Item>();
        for (int i = 0; i < keyInt.Count; i++)
        {
            int key = int.Parse(keyInt[i].InnerText);
            Item value = new Item();
            value.id = int.Parse(valueItem[i].Attributes["id"].Value);
            value.num = int.Parse(valueItem[i].Attributes["num"].Value);
            this.itemDic.Add(key, value);
        }
    }
}

存取练习
//封装一个将信息存到一个XML文件中的方法
    public void SaveData(string fileName)
    {
        //决定存储路径
        string path = Application.persistentDataPath + "/" + fileName + ".xml";

        Debug.Log(Application.persistentDataPath);
        //5个步骤

        //1.创建我们的Xml文本 
        XmlDocument xml = new XmlDocument();

        //2.添加固定内容
        XmlDeclaration xmlDec = xml.CreateXmlDeclaration("1.0", "UTF-8", "");
        xml.AppendChild(xmlDec);

        //3.添加根节点
        XmlElement playerInfo = xml.CreateElement("PlayerInfo");
        xml.AppendChild(playerInfo);

        //4.添加子节点 或者 属性相关
        XmlElement name = xml.CreateElement("name");
        name.InnerText = this.name;
        playerInfo.AppendChild(name);

        XmlElement atk = xml.CreateElement("atk");
        atk.InnerText = this.atk.ToString();
        playerInfo.AppendChild(atk);

        XmlElement def = xml.CreateElement("def");
        def.InnerText = this.def.ToString();
        playerInfo.AppendChild(def);

        XmlElement moveSpeed = xml.CreateElement("moveSpeed");
        moveSpeed.InnerText = this.moveSpeed.ToString();
        playerInfo.AppendChild(moveSpeed);

        XmlElement roundSpeed = xml.CreateElement("roundSpeed");
        roundSpeed.InnerText = this.roundSpeed.ToString();
        playerInfo.AppendChild(roundSpeed);

        //weapon
        XmlElement weapon = xml.CreateElement("weapon");
        
        XmlElement id = xml.CreateElement("id");
        id.InnerText = this.weapon.id.ToString();
        weapon.AppendChild(id);
        XmlElement num = xml.CreateElement("num");
        num.InnerText = this.weapon.num.ToString();
        weapon.AppendChild(num);

        playerInfo.AppendChild(weapon);

        //listInt
        XmlElement listInt = xml.CreateElement("listInt");
        for (int i = 0; i < this.listInt.Count; i++)
        {
            XmlElement intNode = xml.CreateElement("int");
            intNode.InnerText = this.listInt[i].ToString();
            listInt.AppendChild(intNode);
        }
        playerInfo.AppendChild(listInt);

        //itemList
        XmlElement itemList = xml.CreateElement("itemList");

        for (int i = 0; i < this.itemList.Count; i++)
        {
            XmlElement itemNode = xml.CreateElement("Item");
            itemNode.SetAttribute("id", this.itemList[i].id.ToString());
            itemNode.SetAttribute("num", this.itemList[i].num.ToString());
            itemList.AppendChild(itemNode);
        }

        playerInfo.AppendChild(itemList);

        //itemDic
        XmlElement itemDic = xml.CreateElement("itemDic");

        foreach (int key in this.itemDic.Keys)
        {
            //key
            XmlElement intNode = xml.CreateElement("int");
            intNode.InnerText = key.ToString();
            itemDic.AppendChild(intNode);
            //value
            XmlElement itemNode = xml.CreateElement("Item");
            itemNode.SetAttribute("id", this.itemDic[key].id.ToString());
            itemNode.SetAttribute("num", this.itemDic[key].num.ToString());
            itemDic.AppendChild(itemNode);
        }

        playerInfo.AppendChild(itemDic);

        //5.存储
        xml.Save(path);
    }

🅰️


⭐【Unityc#专题篇】之c#进阶篇】

⭐【Unityc#专题篇】之c#核心篇】

⭐【Unityc#专题篇】之c#基础篇】

⭐【Unity-c#专题篇】之c#入门篇】

【Unityc#专题篇】—进阶章题单实践练习

⭐【Unityc#专题篇】—基础章题单实践练习

【Unityc#专题篇】—核心章题单实践练习


你们的点赞👍 收藏⭐ 留言📝 关注✅是我持续创作,输出优质内容的最大动力!


在这里插入图片描述


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

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

相关文章

【周末闲谈】关于“数据库”你又知道多少?

个人主页&#xff1a;【&#x1f60a;个人主页】 系列专栏&#xff1a;【❤️周末闲谈】 系列目录 ✨第一周 二进制VS三进制 ✨第二周 文心一言&#xff0c;模仿还是超越&#xff1f; ✨第二周 畅想AR 文章目录 系列目录前言数据库数据库的五大特点数据库介绍数据库管理系统&a…

Linux命令200例:head用于显示文件的开头部分(常用)

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

2023-08-20 LeetCode每日一题(判断根结点是否等于子结点之和)

2023-08-20每日一题 一、题目编号 判断根结点是否等于子结点之和二、题目链接 点击跳转到题目位置 三、题目描述 给你一个 二叉树 的根结点 root&#xff0c;该二叉树由恰好 3 个结点组成&#xff1a;根结点、左子结点和右子结点。 如果根结点值等于两个子结点值之和&…

.fargo后缀勒索病毒|勒索病毒解密恢复|fargo勒索病毒解密|勒索病毒解密恢复|数据库恢复

fargo勒索病毒概述&#xff0c;fargo勒索病毒解密恢复及日常防护建议 目录&#xff1a; fargo勒索病毒介绍感染fargo勒索病毒后的表现fargo勒索病毒的感染形式如何恢复.fargo后缀勒索病毒fargo勒索病毒日常防护建议 简介&#xff1a; 河北某有限公司的财务系统&#xff0c;由…

下线40万辆,欧拉汽车推出2023款好猫尊荣型和GT木兰版

欧拉汽车是中国新能源汽车制造商&#xff0c;成立于2018年。截至目前&#xff0c;已经下线了40万辆整车&#xff0c;可见其在市场的影响力和生产实力。为了庆祝这一里程碑&#xff0c;欧拉汽车推出了品牌书《欧拉将爱进行到底》&#xff0c;在其中讲述了欧拉汽车的发展历程和未…

2000-2021年全国各省份农业碳排放数据(原始数据+测算过程+碳排放的测算结果)

2000-2021年全国各省份农业碳排放数据&#xff08;原始数据测算过程碳排放的测算结果&#xff09; 1、时间&#xff1a;2000-2021年 2、范围&#xff1a;全国31省市 3、指标&#xff1a;化肥使用量(万吨)、塑料薄膜使用量(吨)、农用柴油使用量&#xff08;万吨&#xff09;、…

数据结构 - 语句的频度和时间复杂度

一、语句频度&#xff1a; 算法的运行时间 Σ每条语句的执行次数X该语句执行一次所需的时间每条语句的执行次数&#xff0c;也称为&#xff1a;语句的频度结合上面两点&#xff0c;可知&#xff1a;算法的运行时间 Σ每条语句的频度X该语句执行一次所需的时间 二、语句执行…

【产品规划】功能需求说明书概述

文章目录 1、瀑布流方法论简介2、产品需求文档&#xff08;PRD&#xff09;简介3、产品需求文档的基本要素4、编写产品需求文档5、优秀产品需求文档的特点6、与产品需求文档相似的其他文档 1、瀑布流方法论简介 2、产品需求文档&#xff08;PRD&#xff09;简介 3、产品需求文档…

【汇编语言】使用DS和[address]实现字的传送

文章目录 要解决的问题&#xff1a;CPU从内存单元中读取数据字的传送 要解决的问题&#xff1a;CPU从内存单元中读取数据 1、要求&#xff1a;CPU要读取一个内存单元时&#xff0c;必须先给出这个内存单元的地址&#xff1b; 2、原理&#xff1a;8086设备中&#xff0c;内存地…

Kotlin开发笔记:函数式编程

Kotlin开发笔记&#xff1a;函数式编程 什么是函数式编程 简单来说&#xff0c;我们之前接触到的编程的主流就是命令式编程&#xff0c;我们需要告诉计算机做什么和如何做。而函数式编程的意思就是我们只需要告诉计算机我们想做什么&#xff0c;计算机会帮助我们实现如何做。我…

ubuntu20搭建环境使用的一下指令

1.更新源 sudo vim etc/apt/sources.listdeb http://mirrors.aliyun.com/ubuntu/ xenial main deb-src http://mirrors.aliyun.com/ubuntu/ xenial maindeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates…

小素数,大智慧

小素数&#xff0c;大智慧 定义判断方法方法1方法2方法3方法4方法5方法6方法7 定义 素数&#xff08;质数&#xff09;&#xff1a;在大于 1 的自然数中&#xff0c;只有 1 和该数本身两个因数的数 素数&#xff08;质数&#xff09;&#xff1a;在大于1的自然数中&#xff0c;…

No114.精选前端面试题,享受每天的挑战和学习

文章目录 vue3中的ref、toRef、toRefs说明下TS的优缺点说下函数式组件说下函数式编程 vue3中的ref、toRef、toRefs 下面是对Vue 3中的ref、toRef和toRefs进行比较的表格&#xff1a; reftoReftoRefs参数类型值类型或引用类型响应式对象响应式对象返回值Ref 对象Ref 对象响应式…

简单认识Docker的资源控制

文章目录 一、CPU资源限制1.设置CPU使用率上限2.设置CPU资源占用比&#xff08;设置多个容器才有效&#xff09;3.设置容器与CPU绑核 二、内存资源限制三、对磁盘I/O配额的限制 一、CPU资源限制 1.设置CPU使用率上限 Linux通过CFS&#xff08;Completely Fair Scheduler&#…

【简单认识Docker基本管理】

文章目录 一、Docker概述1、定义2.容器化流行的原因3.Docker和虚拟机的区别4.Docker核心概念 二、安装docker三、镜像管理1.搜索镜像2.下载&#xff08;拉取&#xff09;镜像3.查看已下载镜像4.查看镜像详细信息5.修改镜像标签6.删除镜像7.导出镜像文件和拉取本地镜像文件8.上传…

如何在Linux系统上搭建自己的FRP内网穿透

前言 我有一个1核1G的服务器有公网IP但是这个1核1G的服务器太垃圾了,几乎什么都跑不起来,不过网速还行,那我本地还有一个物理主机是一个4核4G的,那我就可以把这台主机安装上linux系统当成一个服务器来使用,然后把网络代理到公网IP上.使用内网穿透这篇文章也就出现了. FRP简介 F…

服务器CPU飚高排查

排查思路 当正在运行的Java服务导致服务器的CPU突然飙高时&#xff0c;我们该如何排查定位到哪个接口的哪行代码导致CPU飙高的问题呢&#xff1f;我主要提供两个方案&#xff1a; jstackarthas 准备工作 代码准备 现在需要准备一段可以让服务器CPU飙高的代码以及把代码部署…

鑫达惠购系统APP开发的功能架构介绍

鑫达惠购是一款新电商模式的购物分销系统&#xff0c;基于分销裂变的商业价值行为&#xff0c;快速地分享邀请用户注册。这个系统的模式有个特别的亮点&#xff0c;基于全网公排的模式快速推动用户在商城上的购买活动。 鑫达惠购客户端系统功能 包含的功能有&#xff1a;商城模…

memset の 那些事儿 (C++)

如果你在编程时开了一个数组 int a[100010] 这是后你想把他全部赋值为一个很大的值&#xff08;可能你用它来取min&#xff09; 这时候&#xff0c;应该这样写 for (int i 0; i < 100010; i ) a[i] 0x3f3f3f3f //0x3f3f3f3f 是一个比较接近int_max的一个数&#xff0…

机器学习笔记 - 使用VGG16深度学习模型进行图像相似度比较

一、简述 VGG16 是一个强大的预训练模型,可用于识别图像之间的相似性。通过使用该模型,我们可以从不同图像中提取高级特征并进行比较以识别相似性。该技术具有广泛的应用,从图像搜索和推荐系统到安全和监控。 在本文中,将利用该模型来查找两个图像之间的相似性。 …