商城网站建设制作设计,优秀企业网站模板下载,自己的网站怎么做实时监控,关键词app下载本文为个人学习笔记整理#xff0c;仅供交流参考#xff0c;非专业教学资料#xff0c;内容请自行甄别。 通过学习获取的图片仅可用于个人技术研究#xff08;如测试下载逻辑、解析代码#xff09;#xff0c;不得用于商业用途#xff08;如制作产品素材、二次分发… 本文为个人学习笔记整理仅供交流参考非专业教学资料内容请自行甄别。 通过学习获取的图片仅可用于个人技术研究如测试下载逻辑、解析代码不得用于商业用途如制作产品素材、二次分发也不能传播涉及版权或隐私的内容。 文章目录前言一、AI扩图1.1、概述1.2、项目实现前言 本篇主要介绍在图库类型的项目中如何运用AI对图片进行一系列的优化操作。本篇使用到的是阿里云百炼。 一、AI扩图
1.1、概述 阿里云百炼的官方文档阿里云百炼 调用大模型首先需要获取API Key这一块跟着文档的步骤即可实现 在本项目中用到的是图像画面扩展的功能 查看官方文档该API采用的是异步调用的模式即分为创建提交任务查询任务结果两部分
创建任务获取任务ID接口返回任务ID可根据任务ID查询图像生成的结果。该 task_id的查询有效期为 24 小时。使用步骤1中获取的 task_id通过 GET 请求轮询任务查询接口直到task_status 变为 SUCCEEDED。任务成功后响应中会包含生成的图像 URL。 创建任务这一步一定是要在后端实现的因为调用接口涉及到API key这样的敏感信息是不能存在前端的。而轮询获取任务结果的操作则是放在了前端通过定时器每隔一段时间向后端发送请求获取最新的结果。
1.2、项目实现 首先是要在配置文件中对API key进行设置 然后编写创建任务和获取任务结果的代码这里采用直接发送Http请求的方式对应的请求参数和示例如图
Slf4j
Component
public class AliyunAIService {Value(${aliYunAi.apiKey})private String apiKey;/*** 创建任务获取任务ID请求地址*/private final String createTaskHttpPostUrl https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/out-painting;/*** 查询任务结果请求地址*/private final String queryTaskResHttpGetUrl https://dashscope.aliyuncs.com/api/v1/tasks/;/*** 创建任务获取任务ID** param request* return*/public CreateOutPaintingTaskResponse createTaskHttpPost(CreateOutPaintingTaskRequest request) {ThrowUtils.throwIf(ObjUtil.isEmpty(request), ErrorCode.PARAMS_ERROR, 请求参数为空);// 发送POST请求HttpRequest httpRequest HttpRequest.post(createTaskHttpPostUrl).header(X-DashScope-Async, enable).header(Authorization, Bearer apiKey).header(Content-Type, application/json).body(JSONUtil.toJsonStr(request));//解析结果try (HttpResponse httpResponse httpRequest.execute()) {ThrowUtils.throwIf(!httpResponse.isOk(), ErrorCode.OPERATION_ERROR, 创建任务失败);CreateOutPaintingTaskResponse response JSONUtil.toBean(httpResponse.body(), CreateOutPaintingTaskResponse.class);ThrowUtils.throwIf(ObjUtil.isEmpty(response), ErrorCode.OPERATION_ERROR, 响应结果为空);ThrowUtils.throwIf(!response.getOutput().getTaskStatus().equals(PENDING), ErrorCode.OPERATION_ERROR, 响应状态异常);return response;}}/*** 根据任务ID查询任务结果* 这里不能因为返回的不是success就返回前端失败因为前端需要轮询可能任务在处理中* param taskId* return*/public GetOutPaintingTaskResponse createQueryTaskResHttpGet(String taskId) {log.info(任务ID:{},开始执行,taskId);ThrowUtils.throwIf(StrUtil.isBlank(taskId), ErrorCode.PARAMS_ERROR, 请求参数为空);// 发送Get请求HttpRequest httpRequest HttpRequest.get(queryTaskResHttpGetUrl taskId).header(Authorization, Bearer apiKey);//解析结果try (HttpResponse httpResponse httpRequest.execute()) {GetOutPaintingTaskResponse response JSONUtil.toBean(httpResponse.body(), GetOutPaintingTaskResponse.class);ThrowUtils.throwIf(ObjUtil.isEmpty(response), ErrorCode.OPERATION_ERROR, 响应结果为空);log.info(任务ID:{},执行完成,taskId);return response;}}
}扩图任务请求封装类在xScale和yScale属性上加入了jackson的JsonProperty注解原因是Spring MVC对于属性名第二个字母大写的情况无法进行映射。注意这里第二个字母大写只是为了和接口响应的值相对应将接口返回的x_scaley_scale转换为了规范的驼峰命名。在自定义实体类的情况下应该避免这样的命名方式如email不要定义成eMail。
/*** 扩图任务请求类*/
Data
public class CreateOutPaintingTaskRequest implements Serializable {/*** 模型例如 image-out-painting*/private String model image-out-painting;/*** 输入图像信息*/private Input input;/*** 图像处理参数*/private Parameters parameters;Datapublic static class Input {/*** 必选图像 URL*/Alias(image_url)private String imageUrl;}Datapublic static class Parameters implements Serializable {/*** 可选逆时针旋转角度默认值 0取值范围 [0, 359]*/private Integer angle;/*** 可选输出图像的宽高比默认空字符串不设置宽高比* 可选值[, 1:1, 3:4, 4:3, 9:16, 16:9]*/Alias(output_ratio)private String outputRatio;/*** 可选图像居中在水平方向上按比例扩展默认值 1.0范围 [1.0, 3.0]*/Alias(x_scale)JsonProperty(xScale)private Float xScale;/*** 可选图像居中在垂直方向上按比例扩展默认值 1.0范围 [1.0, 3.0]*/Alias(y_scale)JsonProperty(yScale)private Float yScale;/*** 可选在图像上方添加像素默认值 0*/Alias(top_offset)private Integer topOffset;/*** 可选在图像下方添加像素默认值 0*/Alias(bottom_offset)private Integer bottomOffset;/*** 可选在图像左侧添加像素默认值 0*/Alias(left_offset)private Integer leftOffset;/*** 可选在图像右侧添加像素默认值 0*/Alias(right_offset)private Integer rightOffset;/*** 可选开启图像最佳质量模式默认值 false* 若为 true耗时会成倍增加*/Alias(best_quality)private Boolean bestQuality;/*** 可选限制模型生成的图像文件大小默认值 true* - 单边长度 10000输出图像文件大小限制为 5MB 以下* - 单边长度 10000输出图像文件大小限制为 10MB 以下*/Alias(limit_image_size)private Boolean limitImageSize;/*** 可选添加 Generated by AI 水印默认值 true*/Alias(add_watermark)private Boolean addWatermark false;}
}扩图任务响应封装类
/*** 扩图任务响应类*/
Data
NoArgsConstructor
AllArgsConstructor
public class CreateOutPaintingTaskResponse {private Output output;/*** 表示任务的输出信息*/Datapublic static class Output {/*** 任务 ID*/private String taskId;/*** 任务状态* ul* liPENDING排队中/li* liRUNNING处理中/li* liSUSPENDED挂起/li* liSUCCEEDED执行成功/li* liFAILED执行失败/li* liUNKNOWN任务不存在或状态未知/li* /ul*/private String taskStatus;}/*** 接口错误码。* p接口成功请求不会返回该参数。/p*/private String code;/*** 接口错误信息。* p接口成功请求不会返回该参数。/p*/private String message;/*** 请求唯一标识。* p可用于请求明细溯源和问题排查。/p*/private String requestId;}查询任务响应封装类
/*** 查询任务响应类*/
Data
NoArgsConstructor
AllArgsConstructor
public class GetOutPaintingTaskResponse {/*** 请求唯一标识*/private String requestId;/*** 输出信息*/private Output output;/*** 表示任务的输出信息*/Datapublic static class Output {/*** 任务 ID*/private String taskId;/*** 任务状态* ul* liPENDING排队中/li* liRUNNING处理中/li* liSUSPENDED挂起/li* liSUCCEEDED执行成功/li* liFAILED执行失败/li* liUNKNOWN任务不存在或状态未知/li* /ul*/private String taskStatus;/*** 提交时间* 格式YYYY-MM-DD HH:mm:ss.SSS*/private String submitTime;/*** 调度时间* 格式YYYY-MM-DD HH:mm:ss.SSS*/private String scheduledTime;/*** 结束时间* 格式YYYY-MM-DD HH:mm:ss.SSS*/private String endTime;/*** 输出图像的 URL*/private String outputImageUrl;/*** 接口错误码* p接口成功请求不会返回该参数/p*/private String code;/*** 接口错误信息* p接口成功请求不会返回该参数/p*/private String message;/*** 任务指标信息*/private TaskMetrics taskMetrics;}/*** 表示任务的统计信息*/Datapublic static class TaskMetrics {/*** 总任务数*/private Integer total;/*** 成功任务数*/private Integer succeeded;/*** 失败任务数*/private Integer failed;}
}前端部分则是要定义一个定时器并且需要记录后端传递的taskId。要注意定时器需要关闭的场景后端明确返回成功或失败接口失败接口报错关闭页面时都需要清理计时器并且置空taskId。
//轮询定时器
let pollingTimer: NodeJS.Timeout null
const loading refboolean(false)/*** 开启轮询*/
const startPolling () {if (!taskId.value) {return}pollingTimer setInterval(async () {try {//调用后端查询AI处理图片任务结果的接口const resp await queryPicHandletaskUsingGet({taskId: taskId.value,})//接口成功if (resp.data.code 0) {//成功if (resp.data.data?.output?.taskStatus SUCCEEDED) {aiHandleResUrl.value resp.data.data?.output?.outputImageUrlstopPolling()}//失败if (resp.data.data?.output?.taskStatus FAILED) {stopPolling()}} //接口失败else {stopPolling()}} catch (error) {console.log(调用后端查询AI处理图片任务结果的接口错误, error)stopPolling()}}, 3000)
}/*** 结束轮询*/
function stopPolling() {if (pollingTimer) {clearInterval(pollingTimer)loading.value falsepollingTimer nulltaskId.value null}
}/**-* 生成图片 调用后端创建AI处理图片任务接口*/
async function doAIHandler() {loading.value trueconst resp await createPicHandletaskUsingPost({pictureId: props.picture?.id,parameters: {xScale: 2,yScale: 2,},})if (resp.data.code 0) {message.success(后台处理中请勿关闭窗口稍后查证)//记录任务IDtaskId.value resp.data.data?.output?.taskId//开启任务轮询startPolling()} else {message.error(resp.data.message)}
}onUnmounted(() {stopPolling()
})最终效果AI扩图有一定的限制也应在前端给予友好的提示