基于 Trae + DeepSeek 的 Vibe Coding 实践指南(六):实战阿里云图片内容审核全栈项目
目录


前言
大家好啊,我是云泽Q,欢迎阅读我的文章,一名热爱计算机技术的在校大学生,喜欢在课余时间做一些计算机技术的总结性文章,希望我的文章能为你解答困惑~
该篇为图片审核项目的全栈实现过程~
一、VibeCoding实现图片内容审核功能
现在开始做图片智能审核的项目,如果你看了前4篇文章,也就可以猜到我们接下来要干嘛了,在trae的该路径下创建一个文件夹
然后在Trae中打开文件夹,就选我们刚刚新建的文件夹
该项目依旧可以加入前面文章所提到的创建spring boot项目的skills,然后让它创建 Spring Boot 项目
1.1 图片内容安全能力介绍
我依旧把相关能力介绍的链接贴到这里,图片内容安全能力介绍,可以自己打开去看我们具体实现的是一个怎样的功能,我这里之说我们待会代码中需要使用的字段,文档和视频OCR那里的阅读方法是一样的
红框标注为我们项目中具体实现的内容,其他内容在做完后可以自行实现
返回数据我们待会代码中要使用的字段是Suggestion和Label,Scene,Rate
我们在接入指引这里直接进入开通服务即可,注意,前提是你的阿里云账户上有钱,充个5块够用了
1.2 图片内容安全示例代码
图片内容安全示例代码
首先说明一下,不要按照官方给的配置环境变量的方法来,我们做视频OCR项目的时候是把阿里云的两个key拿出来放到项目中了,图片的意思是把key配置到windows的环境变量中,但是这种方法并不安全,就按照我前面的方法,把key放到Java代码中的配置文件即可

我们同样在trae建一个文件/类把代码复制过来ScanImage
/*
引入依赖包
<!-- https://mvnrepository.com/artifact/com.aliyun/imageaudit20191230 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>imageaudit20191230</artifactId>
<version>${aliyun.imageaudit.version}</version>
</dependency>
*/
import com.aliyun.imageaudit20191230.models.ScanImageAdvanceRequest;
import com.aliyun.imageaudit20191230.models.ScanImageResponse;
import com.aliyun.tea.TeaModel;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
public class ScanImage {
public static com.aliyun.imageaudit20191230.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
/*
初始化配置对象com.aliyun.teaopenapi.models.Config
Config对象存放AccessKeyId、AccessKeySecret、endpoint等配置
*/
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
.setAccessKeyId(accessKeyId)
.setAccessKeySecret(accessKeySecret);
// 访问的域名
config.endpoint = "imageaudit.cn-shanghai.aliyuncs.com";
return new com.aliyun.imageaudit20191230.Client(config);
}
public static void main(String[] args) throws Exception {
// 创建AccessKey ID和AccessKey Secret,请参考https://help.aliyun.com/document_detail/175144.html
// 如果您使用的是RAM用户的AccessKey,还需要为子账号授予权限AliyunVIAPIFullAccess,请参考https://help.aliyun.com/document_detail/145025.html
// 从环境变量读取配置的AccessKey ID和AccessKey Secret。运行代码示例前必须先配置环境变量。
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
com.aliyun.imageaudit20191230.Client client = ScanImage.createClient(accessKeyId, accessKeySecret);
// 场景一,使用本地文件
// InputStream inputStream1 = new FileInputStream(new File("/tmp/ScanImage1.png"));
// InputStream inputStream2 = new FileInputStream(new File("/tmp/ScanImage2.png"));
// 场景二,使用任意可访问的url
URL url = new URL("http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/facebody/DetectFace/DetectFace1.png");
InputStream inputStream1 = url.openConnection().getInputStream();
URL url2 = new URL("http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/facebody/DetectFace/DetectFace2.png");
InputStream inputStream2 = url2.openConnection().getInputStream();
ScanImageAdvanceRequest.ScanImageAdvanceRequestTask task0 = new ScanImageAdvanceRequest.ScanImageAdvanceRequestTask();
task0.setDataId("uuid-xxxx-xxxx-123456");
task0.setImageTimeMillisecond(1L);
task0.setInterval(1);
task0.setMaxFrames(1);
task0.setImageURLObject(inputStream1);
ScanImageAdvanceRequest.ScanImageAdvanceRequestTask task1 = new ScanImageAdvanceRequest.ScanImageAdvanceRequestTask();
task1.setDataId("uuid-xxxx-xxxx-1234567");
task1.setImageTimeMillisecond(1L);
task1.setInterval(1);
task1.setMaxFrames(1);
task1.setImageURLObject(inputStream2);
List<ScanImageAdvanceRequest.ScanImageAdvanceRequestTask> taskList = new ArrayList<>();
taskList.add(task0);
taskList.add(task1);
List<String> sceneList = new ArrayList<>();
sceneList.add("logo");
sceneList.add("porn");
com.aliyun.imageaudit20191230.models.ScanImageAdvanceRequest scanImageAdvanceRequest = new com.aliyun.imageaudit20191230.models.ScanImageAdvanceRequest()
.setTask(taskList)
.setScene(sceneList);
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
ScanImageResponse scanImageResponse = client.scanImageAdvance(scanImageAdvanceRequest, runtime);
// 获取整体结果
System.out.println(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(scanImageResponse)));
// 获取单个字段
System.out.println(scanImageResponse.getBody().getData());
} catch (com.aliyun.tea.TeaException teaException) {
// 获取整体报错信息
System.out.println(com.aliyun.teautil.Common.toJSONString(teaException));
// 获取单个字段
System.out.println(teaException.getCode());
}
}
}
1.3 图片内容安全SDK接入
我们代码中由于使用了阿里云的工具,我们需要把工具拿过来,就是接入图片内容安全SDK
可支持的SDK列表
获取SDK

可以点链接自行进去拿或者直接复制我下面的
<!-- Source: https://mvnrepository.com/artifact/com.aliyun/imageaudit20191230 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>imageaudit20191230</artifactId>
<version>2.0.7</version>
<scope>compile</scope>
</dependency>
复制完成以后放到代码的pom中,放好保存一下就好了
在运行程序之前记得把自己阿里云的key放进去
这里它默认可以同时检测两张图片,返回两张图片的结果,且给了两个示例图片,可以把网址复制到电脑浏览器上下载下来

我们如果只想让它同时检测一张图片,就可以注释掉其中一个url,这里我注释url,保留url2。task0代表第0个任务,我们保留了url2,所以task0都可以注释掉,留task1,我这里就不注释了,就解释一下有这个方法
返回结果的位置如图所示,这里我们自己再加几个打印的文字,方便程序运行起来观察
然后我们右键run Java,看能否输出正确结果
可以看到终端的结果,其中一个图片:"Suggestion":"pass","Rate":99.9,"Label":"normal","Scene":"logo"
意味着图片中场景存在特殊的logo,但是是一张正常图片,正常概率是百分之99.9,检测情况是通过的
另一张图片:"Suggestion":"pass","Rate":99.9,"Label":"normal","Scene":"porn"
图片场景是鉴黄,因为图片中的小美穿着一个不太明显的吊带,是一张正常图片,概率是百分之99.9正常,检测情况是通过的
所以我们前端要展示的结果也就是这几个变量,而仔细看终端信息可以发现,这些信息都在SubResults中,这些信息都是和前面的官方文档的返回结果一一对应的,有两个SubResults是因为代码在执行过程中对图片进行了两次检测,现在我们知道输出了什么结果,后面前端我们就清楚怎么做了
二、后端代码编写
现在后端运行的时候只能右键运行,还不是一个完整的Java项目,现在要把它在特定架构下将代码组织起来
2.1 阿里云示例代码重构为 Spring Boot 项目
现在新建一个对话窗口,给予提示词让AI干这个活
# 阿里云示例代码重构为 Spring Boot 项目
## 任务目标
将提供的阿里云官方示例代码,在test包下的(ScanImage.java)进行合理的归类和整理,转换为一个结构清晰、便于工程化管理的 Spring Boot 后端项目。
要求:
1. 后续前端会上传本地图片给到后端进行处理
2. 把现有类ScanImage.java中已经确定执行的输出结果即:System.out.println(com.aliyun.teautil.Common.toJSONString(TeaModel.buildMap(scanImageResponse)))的打印内容;作为JSON返回给前端的数据,前端会以这个格式进行解析.
## 具体要求
### 1. 代码结构划分
按照 Spring Boot 标准项目结构进行组织:
- **Controller 层**:处理 HTTP 请求的代码放入 `controller` 包下
- **Service 层**:业务逻辑代码放入 `service` 包下(如有必要,可进一步分为 `service.impl`)
- **常量类**:常量定义集中放入 `constant` 包下
- **配置类**:可抽离的配置(如 Bean 定义、属性加载等)放入 `config` 包下
- **其他**:根据实际情况可能需要 `model`(实体/DTO)、`utils`(工具类)等,按 Spring Boot 惯例放置
### 2. 日志记录
- 使用 **SLF4J** 作为日志门面,具体实现推荐 **Logback**
- 日志配置文件(如 `logback-spring.xml`)放置在 `src/main/resources` 下
- 日志输出路径:项目根目录下的 `logs/app.log`
- 建议按日期或大小滚动,保留适当历史
- 控制台输出可保留用于开发环境
### 3. 注释规范
- 所有代码注释使用**中文**,便于团队维护
- 关键类、方法、字段一定要添加清晰的功能说明及必要的参数/返回值注释
### 4. 工程化管理目标
- 代码层次分明,职责单一
- 配置外部化(使用 `application.properties`)
- 遵循 Spring Boot 约定,便于后续集成测试、部署与扩展
- 遵循 REST API接口的约定
## 交付成果
请输出完整的项目代码结构,包含:
- 按上述包结构组织的 Java 文件
- 配置文件(日志配置、应用配置等)
- 如有必要,提供 `pom.xml` 依赖说明
- 不要动ScanImage这个类,只需重新生成其他类即可
- 先不着急写代码,先分析和理解我的问题。
> 注意:请先认真阅读并理解原始阿里云示例代码的功能与逻辑,再进行重构。

整个后端重构好之后,我们依旧把两个key放进去,然后再新开一个对话窗口,让它做前端
2.2 前端代码编写
阅读目前的后端代码,保持现在后端返回的JSON结果不变,实现以下功能
1. 上传本地的单个图片的功能,支持点击上传和拖拽上传
2. 页面上选择要进行检测的功能,可以多选,我们只实现如下3个功能,对应关系如下:
---
porn:图片智能鉴黄
terrorism:图片敏感内容识别、图片风险人物识别
live:图片不良场景识别:适用于图片中涉及毒品、赌博、画中画等内容的识别。
---
1. 点击选中的一个或者多个检测功能,然后把图片发给后端处理
2. 后端处理结束后,会把阿里云生成的响应结果以`JSON`的形式返回。
3. 前端必须先熟悉后端返回的JSON结构,然后正确解析这个JSON
**后端数据结构说明:**
- 响应数据路径:response.body.Data.Results[].SubResults[]
- 关键字段:Scene(场景)、Suggestion(建议)、Rate(置信度)、Label(标签)
- Suggestion取值:pass=通过, review=待审核, block=违规
- Scene对应:porn=图片智能鉴黄, terrorism=敏感内容识别, live=不良场景识别
- Label字段:检测结果的分类,与具体的scene对应。
- Rate字段:结果为该分类的概率,取值范围为0~100。值越高,表示越有可能属于该分类。
**处理要求:**
1. 从SubResults数组中提取每个场景的检测结果
2. 将每个场景的Scene、Suggestion、Rate、Label字段提取出来
3. 从而展示对应场景的结果列表
最后前端这里需要分别展示在不同的检测选项下的审核结果,结果分点展示。
如:
- 图片智能鉴黄具体的详细检测结果是什么?
- 敏感内容识别具体的详细检测结果是什么?
- 不良场景识别具体的详细检测结果是什么?
1. 为了更好的打通前后端的交互,必要情况下可以修改后端的代码
2. 前后端做好统一响应,可以利用`ResponseEntity`处理。
3. 前端采用HTML+CSS+JavaScript的技术栈,页面一定要美观,因为你是专业的前端。
4. 需要在控制台输出的同时,前端页面也要展示后端返回给前端的响应数据。方便用户校验。


可以看到确实也还是可以的
结语

更多推荐

所有评论(0)