基于 Spring Boot 实现图片的服务器本地存储及前端回显
??导读:本文探讨了在网站开发中图片存储的各种方法,包括本地文件系统存储、对象存储服务(如阿里云OSS)、数据库存储、分布式文件系统及内容分发网络(CDN)。文中详细对比了这些方法的优缺点,并针对不同规模的应用推荐了相应的存储策略。此外,还提供了一个基于SpringBoot框架实现服务器本地图片存储与回显的具体示例,涵盖了从图片上传到通过网关服务安全访问图片的全过程。
文章目录
- 前言
-
- 文件存储分类
-
- 本地文件系统存储
- 对象存储服务(OSS)
- 数据库存储
- 分布式文件系统
- 内容分发网络(CDN)
- 总结
- 服务器本地图片存储实现
-
- 图片上传实现
-
- Gateway 服务
-
- 将图片访问链接添加到白名单,跳过登录验证
- 过滤器
- Admin 服务
-
- 依赖
- 配置文件
- Controller
- Service
-
- impl
- 错误码枚举类
- 工具类
- 图片回显
-
- 静态资源处理
- 功能测试
前言
在开发网站时,存储图片是常见的需求之一,尤其对于社交平台、电子商务网站等应用。例如社交平台要存储用户头像,要存储用户发布的朋友圈图片,聊天记录图片等等
文件存储分类
为了满足不同场景下的需求,图片存储有多种常见的方式,每种方式都有其适用场景和特点。以下是几种常用的图片存储方式及其优缺点分析
本地文件系统存储
描述:将图片直接保存在Web服务器的本地文件系统中,通常会有一个固定的目录用于存放这些图片文件。
优点:
- 简单易用:实现起来非常简单,适合小型项目快速搭建或者图片较少的项目。
- 成本低廉:初期成本较低,不需要额外支付存储费用。
缺点:
- 扩展性差:随着图片数量的增加,服务器存储空间会变得紧张,需要频繁地扩容。
- 备份困难:需要手动进行备份,且容易出现单点故障。
- 安全性低:服务器直接暴露在互联网上,存在安全隐患。
- 访问速度受限:图片访问速度受限于服务器带宽,如果有多人同时访问,部分用户需要等待。
对象存储服务(OSS)
描述:使用云服务商提供的对象存储服务,如阿里云OSS、AWS S3、Google Cloud Storage等,将图片存储在云端。
优点:
- 高可用性和持久性:提供多副本冗余,确保数据的高可用性和持久性。
- 易于扩展:可以根据实际需求动态调整存储空间,无需担心物理存储限制。
- 安全性高:提供多种安全机制,如访问控制、数据加密等。
- 全球分布:支持全球多区域部署,提高用户访问速度。
- 成本效益:按需付费,适合业务量波动较大的应用。
缺点:
- 成本随业务增长而增加:随着存储和带宽的增加,费用也会相应增加。
- 访问速度受网络影响:网络状况不佳时,图片加载速度可能变慢。
- 依赖第三方服务:需要考虑服务商的服务质量和稳定性。
- 需要严格控制图片安全:如果没有严格做好防控措施,图片一旦被有心之人频繁刷量,会造成巨大的费用
数据库存储
描述:将图片以二进制形式存储在数据库中,通常会使用BLOB(Binary Large Object)字段。
优点:
- 事务一致性:图片和相关数据可以保持事务一致性,适合需要强一致性的应用场景。
- 便于管理:图片和元数据可以集中管理,方便查询和操作。
缺点:
- 性能较差:读取和写入大文件时性能较差,可能会影响数据库的整体性能。
- 存储成本高:数据库存储成本较高,不适合大量图片的存储。
- 备份和恢复复杂:数据库备份和恢复过程较为复杂,且占用较多资源。
分布式文件系统
描述:使用分布式文件系统(如Hadoop HDFS、GlusterFS等)来存储图片,适合大规模分布式存储需求。
优点:
- 高可用性和扩展性:支持横向扩展,可以通过增加节点来提升存储能力和访问性能。
- 容错能力强:具有良好的容错能力,可以自动处理节点故障。
- 成本效益:相对于传统存储方式,成本更低,适合大规模数据存储。
缺点:
- 复杂度高:实现和维护相对复杂,需要专业的运维团队。
- 访问速度受网络影响:网络状况不佳时,访问速度可能受影响。
- 学习曲线陡峭:需要一定的学习成本和技术积累。
内容分发网络(CDN)
描述:结合对象存储服务和CDN,将图片存储在云存储中,并通过CDN加速分发,提高全球用户的访问速度。
优点:
- 全球加速:通过CDN缓存,提高全球用户的访问速度。
- 高可用性和持久性:结合对象存储服务,确保数据的高可用性和持久性。
- 成本效益:按需付费,适合业务量大的应用。
缺点:
- 成本较高:使用CDN会增加一定的成本。
- 配置复杂:需要配置CDN和对象存储服务,相对复杂。
- 也要严格做好防控措施,否则钱包非常危险
总结
选择合适的图片存储方式需要综合考虑项目的规模、预算、性能要求和未来的扩展性。对于小型项目或初创团队,可以先从本地文件系统存储开始,随着业务的增长逐步迁移到对象存储服务或分布式文件系统。对于大型应用或全球用户较多的场景,建议使用对象存储服务结合CDN,以确保高性能和高可用性。
服务器本地图片存储实现
对于个人开发的小网站,如果图片不多,网站访问量也不多,使用服务器本地存储的方式是比较适合的,本文主要讲解SpringBoot项目如何实现图片如何存储到服务器本地以及前端要怎样才能显示服务器中的图片资源
演示项目说明:该项目使用微服务架构开发,请求首先需要通过Gateway网关,然后转给对应的Admin服务,Admin服务中再处理图片的存储和回显
图片上传实现
Gateway 服务
将图片访问链接添加到白名单,跳过登录验证
spring:profiles:active: damWinapplication:name: vrs-gatewaycloud:gateway:routes:- id: vrs-adminuri: lb://vrs-admin/admin/**predicates:- Path=/admin/**filters:- name: TokenValidateargs:whitePathList:- /admin/user/v1/login- /admin/user/v1/has-username- /admin/user/v1/register- /admin/pic/
过滤器
拦截请求,将网关服务的访问域名放置到请求头中,这样Admin服务就可以在请求头中拿到网关服务的访问域名了
package com.vrs.config;import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;import java.net.InetAddress;
import java.net.UnknownHostException;/*** @Author dam* @create 2024/11/21 20:55*/@Component
public class CustomGlobalFilter {@Value("${server.port}")private int serverPort;/*** 将网关服务的域名端口放到请求头中,方便其他服务使用* @return*/@Bean(name = "customGlobalFilter1")public GlobalFilter customGlobalFilter() {return (exchange, chain) -> {ServerHttpRequest request = exchange.getRequest();String hostAndPort = getHostAndPort(request);ServerHttpRequest modifiedRequest = request.mutate().header("X-Gateway-Host", hostAndPort).build();ServerWebExchange modifiedExchange = exchange.mutate().request(modifiedRequest).build();return chain.filter(modifiedExchange);};}/*** 获取网关服务的访问域名端口* @param request* @return*/private String getHostAndPort(ServerHttpRequest request) {try {// 获取请求的主机名和端口String host = request.getURI().getHost();if (host == null) {// 如果请求中没有主机名,使用本地主机名host = InetAddress.getLocalHost().getHostName();}// 获取请求的协议(HTTP或HTTPS)String scheme = request.getURI().getScheme();return scheme + "://" + host + ":" + serverPort;} catch (UnknownHostException e) {return "unknown";}}
}
Admin 服务
依赖
<!-- 图片压缩工具 -->
<dependency><groupId>net.coobird</groupId><artifactId>thumbnailator</artifactId><version>0.4.8</version>
</dependency>
配置文件
设置上传的文件大小限制,请求的大小限制
spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB
Controller
注意:里面有一步是从请求头中获取网关的访问域名,后面再基于网关的访问域名来拼接图片访问路径,不能直接将Admin服务的域名暴露出去,不然用户可能直接绕过网关的登录验证来访问Admin服务
package com.vrs.controller;import com.vrs.convention.result.Result;
import com.vrs.service.PictureService;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.util.Map;/*** @Author dam* @create 2024/11/21 17:00*/
@RequiredArgsConstructor
@RestController
@RequestMapping("/pic/")
public class PictureController {private final PictureService pictureService;/*** 通用上传请求(单个)*/@PostMapping("/upload")public Result<Map<String, Object>> uploadFile(MultipartFile file, HttpServletRequest request) throws Exception {String gatewayHost = request.getHeader("X-Gateway-Host");return pictureService.uploadFile(file, gatewayHost);}
}
Service
package com.vrs.service;import com.vrs.convention.result.Result;
import org.springframework.web.multipart.MultipartFile;import java.util.Map;/*** @Author dam* @create 2024/11/21 17:12*/
public interface PictureService {Result<Map<String, Object>> uploadFile(MultipartFile file, String request);
}
impl
package com.vrs.service.impl;import com.vrs.common.utils.PictureUploadUtil;
import com.vrs.convention.exception.ClientException;
import com.vrs.convention.result.Result;
import com.vrs.convention.result.Results;
import com.vrs.service.PictureService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.util.HashMap;
import java.util.Map;import static com.vrs.common.enums.ErrorCodeEnum.PICTURE_UPLOAD_FAIL;/*** @Author dam* @create 2024/11/21 17:12*/
@Service
public class PictureServiceImpl implements PictureService {@Overridepublic Result<Map<String, Object>> uploadFile(MultipartFile file, String gatewayDomain) {// 上传并返回新文件名称String fileName = PictureUploadUtil.upload(file);String url = gatewayDomain + "/admin" + fileName;Map<String, Object> resultMap = new HashMap<>();resultMap.put("url", url);resultMap.put("fileName", fileName);resultMap.put("originalFileName", file.getOriginalFilename());return Results.success(resultMap);}
}
错误码枚举类
package com.vrs.common.enums;import com.vrs.convention.errorcode.IErrorCode;/*** 用户错误码*/
public enum ErrorCodeEnum implements IErrorCode {PICTURE_UPLOAD_FAIL("B000301", "图片上传失败"),PICTURE_NAME_EXCEED_LENGTH("B000302", "图片名超出长度"),PICTURE_SUFFIX_ERROR("B000302", "图片名没有携带正常后缀名"),PICTURE_TYPE_ERROR("B000302", "图片格式不对,仅限于 .png .jpg .jpeg .gif"),;private final String code;private final String message;ErrorCodeEnum(String code, String message) {this.code = code;this.message = message;}@Overridepublic String code() {return code;}@Overridepublic String message() {return message;}
}
工具类
该工具类主要完成对图片的校验,然后将图片存储到服务器本地,最后返回图片的访问路径
package com.vrs.common.utils;import com.vrs.convention.exception.ClientException;
import com.vrs.convention.exception.ServiceException;
import net.coobird.thumbnailator.Thumbnails;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.Objects;
import java.util.UUID;import static com.vrs.common.enums.ErrorCodeEnum.*;/*** @Author dam* @create 2024/11/21 17:18*/
public class PictureUploadUtil {/*** 资源映射路径 前缀*/public static final String PIC_PREFIX = "/pic";/*** 图片存储的根路径*/public static final String UPLOAD_PATH = System.getProperty("user.dir") + File.separator + "upload";/*** 默认的文件名最大长度 100*/public static final int DEFAULT_FILE_NAME_LENGTH = 100;public static final String upload(MultipartFile file) {int fileNameLength = Objects.requireNonNull(file.getOriginalFilename()).length();if (fileNameLength > DEFAULT_FILE_NAME_LENGTH) {// --if-- 如果图片名称过程,抛异常throw new ClientException(PICTURE_NAME_EXCEED_LENGTH);}String name = file.getOriginalFilename();if (!name.contains(".")) {// --if-- 如果图片没有正常后缀throw new ClientException(PICTURE_SUFFIX_ERROR);} else if (!(name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".gif"))) {// --if-- 校验文件是否为图片类型throw new ClientException(PICTURE_TYPE_ERROR);}String[] split = name.split("\.");// 图片名称String fileName = split[0];// 图片后缀String fileSuffix = split[1];// 获取当前日期LocalDate date = LocalDate.now();// 获取年份int year = date.getYear();// 获取月份int month = date.getMonthValue();// 获取日期int day = date.getDayOfMonth();String dir = File.separator + year + File.separator + month + File.separator + day;File dirFile = new File(UPLOAD_PATH + dir);if (!dirFile.exists()) {// 创建相应日期文件夹dirFile.mkdirs();}// 生成一个唯一IDString uuid = UUID.randomUUID().toString().replace("-", "");// 相对路径String relativePath = dir + File.separator + fileName + "-" + uuid + "." + fileSuffix;// 生成图片要上传到的绝对路径String absPath = UPLOAD_PATH + relativePath;// 压缩存储
// try (InputStream is = file.getInputStream()) {
// // 设置目标文件
// File targetFile = new File(absPath);
//
// // 使用Thumbnails库调整图片分辨率
// Thumbnails.of(is)
// // 设置最大宽度和高度,保持原始比例
// .size(1920, 1080)
// .toFile(targetFile);
// } catch (Exception e) {
// e.printStackTrace();
// throw new ServiceException(e.getMessage());
// }// 直接保存文件(不压缩)try (InputStream is = file.getInputStream()) {File targetFile = new File(absPath);// 将输入流中的数据复制到目标文件中java.nio.file.Files.copy(is, targetFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);} catch (IOException e) {e.printStackTrace();throw new ServiceException(e.getMessage());}return PIC_PREFIX + "/" + year + "/" + month + "/" + day + "/" + fileName + "-" + uuid + "." + fileSuffix;}}
图片回显
图片回显的实现比较简单,添加一个配置类即可
静态资源处理
这段代码的作用是:把网站上显示图片的URL路径(比如 /pic/**)映射到服务器上的一个实际文件夹路径。这样设置后,用户通过浏览器访问这些URL时,就能直接看到存储在服务器指定文件夹里的图片
import com.vrs.common.utils.PictureUploadUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 通用配置** @author dam*/
@Configuration
public class ResourcesConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 将图片请求路径映射到对应的本地图片路径registry.addResourceHandler(PictureUploadUtil.PIC_PREFIX + "/**").addResourceLocations("file:" + PictureUploadUtil.UPLOAD_PATH + "/");}}
功能测试
使用Apifox软件发起一个Post请求,带上要上传的图片

通过链接访问图片,测试通过

相关文章:
基于 Spring Boot 实现图片的服务器本地存储及前端回显
??导读:本文探讨了在网站开发中图片存储的各种方法,包括本地文件系统存储、对象存储服务(如阿里云OSS)、数据库存储、分布式文件系统及内容分发网络(CDN)。文中详细对比了这些方法的优缺点,并…...
深入 TCP VJ-Style
接着 TCP 的文化内涵 继续扯一会儿。 自 30 instruction TCP receive 往前追溯,论文 Jacobson88 源自第一次拥塞崩溃,这篇著名文档在同时期的另一个缘起是另一篇考古文献 [Zhang86] Why TCP Timers Don’t Work Well,后面这篇文献提出了 TCP…...
go高性能单机缓存项目
代码 // Copyright 2021 ByteDance Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apach…...
数据结构绪论
文章目录 绪论数据结构三要素算法 🏡作者主页:点击! 🤖数据结构专栏:点击! ⏰️创作时间:2024年12月12日01点09分 绪论 数据是信息的载体,描述客观事物属性的数、字符及所有能输入…...
前端开发常用四大框架学习难度咋样?
前端开发常用四大框架指的是 jQuery vue react angular jQuery: 学习难度:相对较低特点:jQuery 是一个快速、小巧、功能丰富的 JavaScript 库。它使得 HTML 文档遍历和操作、事件处理、动画和 Ajax 交互更加简单。适用场景&a…...
OWASP 十大安全漏洞的原理
1. Broken Access Control(访问控制失效) 原理:应用程序未正确实施权限检查,导致攻击者通过篡改请求、强制浏览或权限提升等手段绕过访问控制。 攻击手段: 修改 URL、HTML、或 API 请求以访问未经授权的资源。 删除…...
论文 | ChunkRAG: Novel LLM-Chunk Filtering Method for RAG Systems
本文详细介绍了一种新颖的检索增强生成(Retrieval-Augmented Generation, RAG)系统方法——ChunkRAG,该方法通过对文档的分块语义分析和过滤显著提升了生成系统的准确性和可靠性。 1. 研究背景与问题 1.1 检索增强生成的意义 RAG系统结合…...
ORACLE SQL思路: 多行数据有相同字段就合并成一条数据 分页展示
数据 分数表: 学号,科目名(A,B,C),分数 需求 分页列表展示, 如果一个学号的科目有相同的分数, 合并成一条数据,用 拼接 科目名 ORACLE SQL 实现 SELECT Z.*, SUBSTR(DECODE(f…...
SpringBoot 手动实现动态切换数据源 DynamicSource (中)
大家好,我是此林。 SpringBoot 手动实现动态切换数据源 DynamicSource (上)-CSDN博客 在上一篇博客中,我带大家手动实现了一个简易版的数据源切换实现,方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源…...
y3编辑器教学5:触发器2 案例演示
文章目录 一、探索1.1 ECA1.1.1 ECA的定义1.1.2 使用触发器实现瞬间移动效果 1.2 变量1.2.1 什么是变量1.2.2 使用变量存储碎片收集数量并展现 1.3 if语句(魔法效果挂接)1.3.1 地形设置1.3.2 编写能量灌注逻辑1.3.3 编写能量灌注后,实现传送逻…...
数值分析——插值法(二)
文章目录 前言一、Hermite插值1.两点三次Hermite插值2.两点三次Hermite插值的推广3.非标准型Hermite插值 二、三次样条插值1.概念2.三弯矩方程 前言 之前写过Lagrange插值与Newton插值法的内容,这里介绍一些其他的插值方法,顺便复习数值分析. 一、Hermi…...
杨振宁大学物理视频中黄色的字,c#写程序去掉
先看一下效果:(还有改进的余地) 写了个程序消除杨振宁大学物理中黄色的字 我的方法是笨方法,也比较刻板。 1,首先想到,把屏幕打印下来。c#提供了这样一个函数: Bitmap bmp new Bitmap(640, 48…...
uni-app 设置缓存过期时间【跨端开发系列】
🔗 uniapp 跨端开发系列文章:🎀🎀🎀 uni-app 组成和跨端原理 【跨端开发系列】 uni-app 各端差异注意事项 【跨端开发系列】uni-app 离线本地存储方案 【跨端开发系列】uni-app UI库、框架、组件选型指南 【跨端开…...
微信小程序base64图片与临时路径互相转换
1、base64图片转临时路径 /*** 将base64图片转临时路径* param {*} dataurl* param {*} filename* returns*/base64ImgToFile(dataurl, filename "file") {const base64 dataurl; // base64码const time new Date().getTime();const imgPath wx.env.USER_DATA_P…...
蓝桥杯刷题——day2
蓝桥杯刷题——day2 题目一题干题目解析代码 题目二题干解题思路代码 题目一 题干 三步问题。有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶或3阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要…...
5.删除链表的倒数第N个节点
19.删除链表的倒数第N个节点 题目: 19. 删除链表的倒数第 N 个结点 - 力扣(LeetCode) 分析: 要删除倒数第几个节点,那么我们需要怎么做呢?我们需要定义两个指针,快指针和慢指针,…...
自己总结:selenium高阶知识
全篇大概10000字(含代码),建议阅读时间30min 一、等待机制 如果有一些内容是通过Ajax加载的内容,那就需要等待内容加载完毕才能进行下一步操作。 为了避免人为操作等待,会遇到的问题, selenium将等待转换…...
前端怎么预览pdf
1.背景 后台返回了一个在线的pdf地址,需要我这边去做一个pdf的预览(需求1),并且支持配置是否可以下载(需求2),需要在当前页就能预览(需求3)。之前我写过一篇预览pdf的文…...
activemq 的安装部署
下载 https://activemq.apache.org/components/classic/download/# 在/opt目录下载 wget https://dlcdn.apache.org//activemq/5.18.6/apache-activemq-5.18.6-bin.tar.gz解压 tar -zxvf apache-activemq-5.18.6-bin.tar.gz配置java环境 vim /opt/apache-activemq-5.18.6/b…...
【H3CNE邓方鸣】配置链路聚合+2024.12.11
文章目录 链路聚合作用负载分担分类静态聚合动态聚合 链路聚合作用 定义:把连接到统一交换机上的多个物理端口捆绑为一个逻辑端口 增加链路带宽:聚合组内只要还有物理端口存活,链路就不会中断 提供链路可靠性:避免了STP计算&…...
零基础快速入门前端蓝桥杯真题速刷2451.灯的颜色变化(助力保底拿奖不捐款)深入掌握 DOM 选择器与定时器:从交通灯案例到蓝桥杯 Web 考点全解 将原题目扩展成交通灯
2451.灯的颜色变化深入掌握 DOM 选择器与定时器:从交通灯案例到蓝桥杯 Web 考点全解在蓝桥杯 Web 方向竞赛中,DOM 操作与定时器控制是高频考点。本文以一个经典的交通灯控制案例为切入点,全面解析 document.querySelector 的 ID/Class 选择语…...
Windows下OpenClaw安装教程:一键部署Kimi-VL-A3B-Thinking镜像
Windows下OpenClaw安装教程:一键部署Kimi-VL-A3B-Thinking镜像 1. 为什么选择OpenClawKimi-VL组合 上周我在整理电脑上的图片素材时,突然冒出一个想法:如果能有个AI助手帮我自动分类这些图片,还能根据内容生成描述文字该多好。经…...
使用PHP和Xunsearch实现歌曲搜索功能
要打造一款高效的音乐网站,搜索功能绝对是重中之重!试想一下,当用户打开你的音乐网站,输入一首歌名,却发现搜索结果不仅慢,还不精准,那简直就是“用户流失现场”!今天我们聊聊如何用…...
2025届学术党必备的十大降AI率工具推荐
Ai论文网站排名(开题报告、文献综述、降aigc率、降重综合对比) TOP1. 千笔AI TOP2. aipasspaper TOP3. 清北论文 TOP4. 豆包 TOP5. kimi TOP6. deepseek 对于知网AI检测系统来讲,要降低生成文本的可识别性,得从词汇层面施展…...
《新天龙八部3》江山策服务端架设后,如何用GM工具修改数据?完整配置与安全使用教程
《新天龙八部3》GM工具深度配置与安全操作指南 当你在本地环境成功架设《新天龙八部3》江山策服务端后,GM工具将成为你探索游戏机制、测试功能的有力助手。不同于简单的数值修改,专业开发者更关注工具背后的运行逻辑和安全边界。本文将带你从通信协议解析…...
Qwen2-VL-2B-Instruct入门必看:如何编写高效Instruction提升图文匹配精度
Qwen2-VL-2B-Instruct入门必看:如何编写高效Instruction提升图文匹配精度 1. 什么是Qwen2-VL-2B-Instruct Qwen2-VL-2B-Instruct是一个专门用于图文匹配的多模态模型,它能够理解图片和文字之间的深层语义关系。与普通的对话模型不同,这个模…...
如何用Ryujinx模拟器在PC上免费畅玩Switch游戏?
如何用Ryujinx模拟器在PC上免费畅玩Switch游戏? 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 想在电脑上体验《塞尔达传说:王国之泪》的壮丽冒险,…...
GPU显存稳定性终极检测:使用memtest_vulkan保障显卡健康
GPU显存稳定性终极检测:使用memtest_vulkan保障显卡健康 【免费下载链接】memtest_vulkan Vulkan compute tool for testing video memory stability 项目地址: https://gitcode.com/gh_mirrors/me/memtest_vulkan 显卡显存稳定性直接影响你的游戏体验、设计…...
如何用eSearch神奇工具轻松搞定屏幕上的所有操作?
如何用eSearch神奇工具轻松搞定屏幕上的所有操作? 【免费下载链接】eSearch 截屏 离线OCR 搜索翻译 以图搜图 贴图 录屏 万向滚动截屏 屏幕翻译 Screenshot Offline OCR Search Translate Search for picture Paste the picture on the screen Screen recorder Omni…...
Steam游戏挂机终极指南:如何免费获取游戏时长与交易卡牌
Steam游戏挂机终极指南:如何免费获取游戏时长与交易卡牌 【免费下载链接】HourBoostr Two programs for idling Steam game hours and trading cards 项目地址: https://gitcode.com/gh_mirrors/ho/HourBoostr 想要轻松获得Steam游戏时长和珍贵交易卡牌吗&am…...
