在这里插入图片描述

在这里插入图片描述

🎬 云泽Q个人主页

🔥 专栏传送入口: 《C语言》《数据结构》《C++》《Linux》《蓝桥杯系列》《笔试算法》《AI赋能

⛺️遇见安然遇见你,不负代码不负卿~

前言

大家好啊,我是云泽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. 需要在控制台输出的同时,前端页面也要展示后端返回给前端的响应数据。方便用户校验。

在这里插入图片描述
在这里插入图片描述
可以看到确实也还是可以的


结语

在这里插入图片描述

Logo

AtomGit AI 社区提供模型库、数据集、Agent、Token等资源

更多推荐