智能图库模块-Ai图片编辑

本来该功能应该昨天搞完的,但是昨天上午以及下午莫名其妙地去捣鼓了windows terminal和starship美化终端,而且还搞着搞着样式搞出了问题,然后发现win11自带Windows terminal,不需要自行安装,我又升级系统等了一堆时间,属于是纯纯给自己没事找事做了,不过美化后的Windows terminal还是挺好看的捏:

image.png 今天上午刷了一小时面试鸭后,下午就投入到Ai图片编辑模块的学习了。 项目中的Ai扩图采用的阿里云百炼大模型来实现ai编辑的功能,由于官方文档中对于Java SDK的介绍比较少,因此采用http调用的方式,在官方文档中提到:

为了减少等待时间并且避免请求超时,服务采用异步方式提供。您需要发起两个请求: 创建任务:首先发送一个请求创建扩图任务,该请求会返回任务ID。 即:POST https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/out-painting 根据任务ID查询结果:使用上一步获得的任务ID,查询模型生成的结果。 即:GET https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}

也就是我们要发两次http请求才能获得生成后的图片,在官方文档中有给到请求头和请求参数,分别把两个请求的请求头和请求参数丢给Ai来给我们生成Java实体类代码,节省时间。调用Api需要Apikey,因此记得在配置文件上配上Apikey。 跟之前写以图搜图的思路一样,在api目录下创建aliYunAi来存放与该api相关的实体类和方法,创建AliYunAiApi来编写相关代码:

java
复制代码
@Slf4j @Component public class AliYunAIApi { //读取配置文件 @Value("${aliYunAi.apiKey}") private String apiKey; //创建任务地址 public static final String CREATE_OUT_PAINTING_TASK_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image2image/out-painting"; //查询任务状态 public static final String GET_OUT_PAINTING_TASK_URL = "https://dashscope.aliyuncs.com/api/v1/tasks/%s"; //创建任务 public CreateOutPaintingTaskResponse createOutPaintingTask(CreateOutPaintingTaskRequest createOutPaintingTaskRequest){ if (createOutPaintingTaskRequest == null){ throw new BusinessException(ErrorCode.OPERATION_ERROR,"扩图参数为空"); } //发送请求 HttpRequest request = HttpRequest.post(CREATE_OUT_PAINTING_TASK_URL) .header("Authorization", "Bearer " + apiKey) //开启异步处理 .header("X-DashScope-Async", "enable") .header("Content-Type", "application/json") .body(JSONUtil.toJsonStr(createOutPaintingTaskRequest)); //处理响应 try(HttpResponse httpResponse = request.execute()){ if (!httpResponse.isOk()){ log.error("请求异常:{}",httpResponse.body()); throw new BusinessException(ErrorCode.OPERATION_ERROR,"AI扩图失败"); } CreateOutPaintingTaskResponse createOutPaintingTaskResponse = JSONUtil.toBean(httpResponse.body(), CreateOutPaintingTaskResponse.class); if (createOutPaintingTaskResponse.getCode() != null){ String errorMessage = createOutPaintingTaskResponse.getMessage(); log.error("请求异常:{}",errorMessage); throw new BusinessException(ErrorCode.OPERATION_ERROR,"AI扩图失败 " + errorMessage); } return createOutPaintingTaskResponse; } } /** * 查询创建的任务结果 * @param taskId * @return */ public GetOutPaintingTaskResponse getOutPaintingTask(String taskId){ if (taskId == null){ throw new BusinessException(ErrorCode.OPERATION_ERROR,"任务id为空"); } String url = String.format(GET_OUT_PAINTING_TASK_URL,taskId); //处理响应 try(HttpResponse httpResponse = HttpRequest.get(url) .header("Authorization", "Bearer " + apiKey) .execute()){ if (!httpResponse.isOk()){ log.error("请求异常:{}",httpResponse.body()); throw new BusinessException(ErrorCode.OPERATION_ERROR,"获取任务结果失败"); } return JSONUtil.toBean(httpResponse.body(), GetOutPaintingTaskResponse.class); } } }

其中CreateOutPaintingTaskRequest里有两个变量xScaleyScale需要加多一个@JsonProperty的注解,因为Jackson对于第二个字母是大写的参数无法映射,前端如果穿了这两个参数会无法赋值到相应的字段。 前端部分页面的设计不多作记录,因为该请求是需要异步调用的,所以需要对请求进行轮询,为了不让后端因为轮询而导致请求还没完成时导致任务阻塞资源耗尽,采用前端轮询的方式来进行调用,即前端每隔几秒向后端发送请求。像之前编辑图片一样也是采用弹窗组件:

vue
复制代码
<a-modal class="image-out-painting" v-model:open="visible" title="AI 扩图" :footer="false" @cancel="closeModal" > <a-row gutter="16"> <a-col span="12"> <h4>原始图片</h4> <img :src="picture?.url" :alt="picture?.name" style="max-width: 100%" /> </a-col> <a-col span="12"> <h4>扩图结果</h4> <img v-if="resultImageUrl" :src="resultImageUrl" :alt="picture?.name" style="max-width: 100%" /> </a-col> </a-row> <div style="margin-bottom: 16px" /> <a-flex justify="center" gap="16"> <a-button type="primary" :loading="!!taskId" @click="createTask" ghost>生成图片</a-button> <a-button v-if="resultImageUrl" type="primary" :loading="uploading" @click="handleUpload">应用结果</a-button> </a-flex> </a-modal>

在createTask中,编写了创建任务的请求:

ts
复制代码
const createTask = async () => { if (!props.picture?.id) { return } const res = await createPictureOutPaintingTaskUsingPost({ pictureId: props.picture.id, //根据需要设置扩图参数 parameters: { xScale: 2, yScale: 2 } }) if (res.data.code === 0 && res.data.data) { message.success('创建任务成功,耐心等待,请不要退出') console.log(res.data.data.output?.taskId)//打印任务ID taskId.value = res.data.data.output?.taskId //开启轮询 startPolling() } else { message.error('创建任务失败,' + res.data.msg) } }

这里面的starPolling()就是轮询相关的代码,要特别注意的是,在启动轮询后无论任务成功还是失败都要记得及时关闭轮询,有异常也要关闭,不然出问题时难以排查出来:

ts
复制代码
//轮询定时器 let pollingTimer: NodeJs.Timeout = null const startPolling = () => { if (!taskId.value){ return } pollingTimer = setInterval(async () => { try { const res = await getPictureOutPaintingTaskUsingGet({ taskId: taskId.value }) if (res.data.code === 0 && res.data.data) { const taskResult = res.data.data.output if (taskResult?.taskStatus === 'SUCCEEDED'){ message.success('扩图任务执行成功') resultImageUrl.value = taskResult?.outputImageUrl clearPolling() }else if (taskResult?.taskStatus === 'FAILED'){ message.error('扩图任务执行失败') clearPolling() } } }catch (error){ console.log('扩图任务轮询失败',error) message.error('检测任务失败 请稍后重试') clearPolling() } }, 3000)//每3s轮询一次 } //清理轮询 const clearPolling = () => { if (pollingTimer){ clearInterval(pollingTimer) pollingTimer = null taskId.value = null } } onMounted(() =>{ clearPolling() })

这些便是本次学习对我来说有所收获的记录。

0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
shark
作者分享
做了一个月的小程序,终于准备到即将交付的时候了,这段时间里可真是被微信小程序的各种限制折磨的不要不要的,突出一个为难开发者,有几次改代码改到了两点多才改完!小程序的后端技术栈和鱼皮的智能Bi项目采用了差不多的技术栈,通过注解+aop来对接口进行令牌桶限流,用rabbitmq来缓解调用Ai服务的压力,异步生成报告,对于订单采用了自定义线程池结合async+scheduled注解实现定时任务的异步执行,每分钟遍历删除库中的订单,还有些功能等真正交付后再做下总结。唉,不知道这个项目再加上智能图库项目能不能让我这种0相关工作经验的双非往届生有面试机会和找到工作呢,不想再次尝试付出与回报不成正比的滋味了😭😭
8
今天收到了甲方的第一笔付款💰,没想到毕业一年半居然能用自己专业技能接个活赚了点外快,还是有点小高兴的。 这两天的学习状态不太行,我好像总会在经历了持续一段时间的学习后会有两三天学不进的状态🤧,不知道大伙会不会有这种状态,虽然我很想克服这种状态,但心里就好像有东西堵在那影响着学不进去(不知道是不是焦虑),希望明天能恢复状态吧。 转眼到了3月份,接的活的时间也剩下半个月了,下半部分就要开发调用Ai接口的代码和微信支付(感觉好像挺麻烦?)的代码了,同时也需要开始准备看面试题了,想问下各位是怎么使用面试鸭来高效刷题的呢,这两天(可能跟我的状态有关)看面试题总是有种似记住但又没全记住的感觉,上次背八股还是22年秋招的时候,对于一些知识可能还有记得一些,但由于我是0开发经验社招,不知道重点要看哪些好,希望各位大佬能给小弟一点建议🙏
4
这几天没有打卡,不是摆烂了,而是前几天有个朋友推了个活给我问我说做不做,是做一个微信小程序,并且需要调用Ai的接口,他因为工作太忙没有空接这个活,而我本来正在学习Bi项目,打算学完之后写简历刷面试题投简历,所以一开始还在犹豫,觉得自己23届毕业,虽说大学自学了几年Java,但是0相关工作经验,有点没底气,不过后来我拉到了另一个同学来帮忙,那个同学在大厂实习过,有过企业开发的经验,他也乐意加入一起做项目,于是最后便接下了这个活(主要是有钱可以拿)。由于自己是前端苦手,所以也是一边问Ai一边改页面的布局,改到今天觉得差不多了,甲方也觉得ok,后面就准备和同学一起写后端的接口了,在这几天也对着项目需求跟同学讨论了许多功能和结构上的设计,也算是一种积累经验的过程了,希望这一个月的工期内能把项目做好上线,最好是能写到简历上吧,孩子真的很想要一份工作!!这一个月干的活希望不要是白忙活,不然我真的要道心破碎了😭😭😭
7
智能Bi项目-限流优化
7
智能BI项目-调用硅基流动的DeepSeek
19
下载 APP