SpringAI + 千问 实现(拍照识物)拍照识花(附完整代码)
兄弟们,最近通过springAI做了一个小功能,调用阿里的通义千问VL模型(也可以是其他AI模型),实现拍照识花功能。代码可以自取。
代码地址:https://gitcode.com/m0_68450099/pimode
先看效果:
-
上传一张花的图片 → 返回花名
-
可以问“这花适合室内养吗?” → AI结合图片回答问题
-
平均响应1-2秒
再说人话:这就是一个能直接跑通的SpringBoot项目,不是PPT,不是概念,你把代码拉下来,改个API Key,就能看到识别结果。
一、为什么做这个
说实话,市面上AI识花的App很多,拍照就能识别,挺方便。但问题是——那些代码你能拿到吗?能集成到你自己做的系统里吗?
不能。
我想给自己的小项目加个“拍照识物”功能,但又不想从头研究怎么调用AI接口、怎么处理图片、怎么做缓存限流。于是就折腾了这套代码,把它做成一个可以直接用的模板。
识花只是举例。你想识车、识动物、识商品,改几句提示词就行。
二、能干什么
| 功能 | 说明 |
|---|---|
| 图片上传识别 | 支持JPG/PNG/WEBP,最大10MB |
| 附加提问 | 不光是识花,还能问养护、花语 |
| 图片自动压缩 | 省Token = 省钱 |
| 缓存去重 | 相同图片秒返回,不重复调API |
| IP限流 | 一分钟最多10次,防刷 |
| 前端页面 | 拖拽上传,开箱即用 |
三、技术栈(都是Java老熟人了)
| 技术 | 版本 | 干啥用的 |
|---|---|---|
| Java | 17+ | 后端语言 |
| Spring Boot | 3.4.4 | 框架 |
| 通义千问VL | qwen-vl-max-latest | 能看懂图片的AI模型 |
| Spring AI Alibaba | 1.0.0-M6.1 | 阿里官方封装,几行代码调AI |
| Maven | - | 包管理 |
| Vue 3 | - | 前端页面(就一个html文件) |
四、5分钟跑起来
第1步:搞到API Key
去阿里云DashScope控制台注册,创建API Key。
新用户有免费额度,识别几千张花没问题。
第2步:下载代码
bash
git clone https://gitcode.com/m0_68450099/pimode.git cd pimode
第3步:配置Key
1.推荐使用启动命令配置Key
java -jar pimode-1.0-SNAPSHOT.jar --spring.ai.dashscope.api-key=sk-你的key
2.如果在本地使用idea,可以在环境变量中配置key
Run → Edit Configurations → Environment variables →
添加:DASHSCOPE_API_KEY=sk-你的key
3.如果觉得麻烦,可以放在yal中:
打开 src/main/resources/application.yml:
yaml
spring:
ai:
dashscope:
api-key: sk-这里填你的key # 就改这一个地方
第4步:启动后端
bash
mvn clean install mvn spring-boot:run
看到这行字就成功了:
text
🌼 拍照识花服务已启动!访问 http://localhost:8080
第5步:打开前端
用浏览器打开项目根目录下的 index.html。
后端地址填 http://localhost:8080,上传一张花的图片,点识别,等结果。
五、核心代码长啥样
我把关键代码贴出来,你可以看看,不复杂。
1. AI调用(核心就这几行)
java
// 把图片和问题打包
UserMessage msg = new UserMessage(
"这是什么花?只回复花名",
new Media(MediaType.IMAGE_JPEG, 图片文件)
);
// 发给AI,拿结果
String result = chatClient.prompt(msg).call().content();
就是发请求、等响应,和调普通HTTP接口差不多。
2. 图片压缩(省Token的关键)
java
// 压缩到400x400以内,质量50% private static final int MAX_WIDTH = 400; private static final float JPEG_QUALITY = 0.5f;
一张5MB的原图压缩完大概50KB,Token消耗能降90%。缺点是细节可能丢失,如果识别不准可以调大参数。
3. 缓存(相同图片不重复调AI)
java
// 计算图片MD5 String md5 = MD5Util.getMD5(图片字节); // 查缓存 String cached = cacheService.get(md5); if (cached != null) return cached; // 命中,直接返回 // 没命中才调AI
同样的图片第二次识别,从2秒变0.1秒。
4. 限流(防刷)
java
@RateLimit(timeWindow = 60, maxRequests = 10)
@PostMapping("/upload")
public Result<String> upload(...) {
// 同一个IP一分钟最多10次请求
}
六、说实话,缺点也有
这个项目做的时候就定位是“能用”,不是“完美”。有这几个问题,我说清楚:
❌ 没有向量数据库
AI没法“学习”新品种。如果你想让它认识一株市面上没有的花,做不到。除非往system prompt里塞文字描述,但那样每次调用都多消耗Token。
❌ 压缩参数要自己调
400x400、质量0.5这个配置是我在自己测试图上调出来的。你的业务场景可能需要更大或更小的压缩。代码里参数是写死的,你得自己改、自己试。
❌ 缓存存在内存里
服务重启缓存就没了。只适合单机跑。真要上生产,换成Redis也就十几行代码的事,但我没写,留给你自己加。
❌ 限流也是内存版
同样重启丢、多实例不共享。生产环境需要改。
七、怎么改造成其他识别
想改成识车、识动物?改一行提示词就行:
java
// 原来 private static final String DEFAULT_QUESTION = "这是什么花?只回复花名"; // 改成识车 private static final String DEFAULT_QUESTION = "这是什么车的哪款车型?"; // 改成识动物 private static final String DEFAULT_QUESTION = "这是什么动物?";
压缩参数可能需要根据你的图片重新调一下。
八、代码结构速览
text
pimode/ ├── .idea/ # IDEA配置文件 ├── src/ │ ├── main/ │ │ ├── frontend/ # 前端代码,简易前端页面,可直接使用 │ │ ├── java/com/jrl/ │ │ │ ├── annotation/ # 注解 │ │ │ │ └── RateLimit.java # 限流注解 │ │ │ ├── cache/ # 缓存 │ │ │ │ └── ImageCache.java # 内存缓存 │ │ │ ├── common/ # 公共类 │ │ │ │ └── Result.java # 统一响应格式 │ │ │ ├── config/ # 配置类 │ │ │ │ ├── CorsConfig.java # 跨域配置 │ │ │ │ └── WebConfig.java # Web配置(拦截器) │ │ │ ├── controller/ # 控制器 │ │ │ │ └── FlowerController.java │ │ │ ├── interceptor/ # 拦截器 │ │ │ │ └── RateLimitInterceptor.java │ │ │ ├── service/ # 服务层 │ │ │ │ ├── FlowerService.java │ │ │ │ └── impl/ │ │ │ │ └── FlowerServiceImpl.java │ │ │ ├── util/ # 工具类 │ │ │ │ └── MD5Util.java │ │ │ └── FlowApplication.java # 启动类 │ │ ├── resources/ # 配置文件 │ │ │ └── application.yml │ │ └── index.html # 前端页面(根目录) │ └── test/ # 单元测试 ├── README.md └── pom.xml
九、生产环境需要补什么
如果你想把这个项目用到线上,下面这几样东西你自己需要加上:
| 缺啥 | 咋补 |
|---|---|
| 缓存重启丢 | 把ImageCache里的Map换成Redis |
| 限流不持久 | 把RateLimitInterceptor里的Map换成Redis + 令牌桶 |
| 并发高了扛不住 | 加个异步队列,别让AI调用堵住 |
| 想让AI学习新品种 | 接向量数据库做RAG |
| 我的配置不合适你 | 自己调MAX_WIDTH和JPEG_QUALITY |
但这些不在本项目范围内。这个项目给的是一套能跑通的示例,不是生产级框架。
十、最后说两句
这个项目不大,却是一个完整的、能跑的、Java调用通义千问VL的示例。
你觉得有用,就拿去改、拿去用。
你觉得不合适,就看看别的。
代码需要的自取:
👉 https://gitcode.com/m0_68450099/pimode
有问题提Issue,我看到了会回。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)