如何在移動應用中實現AI畫圖?
最近AIGC 簡直是殺瘋了,領導動不動就讓我們在APP 裡引入大語言模型,引入AI畫圖……說搞就搞!本期基於最近在app 裡引入AI畫圖小程式的操作,給大家做一波實踐分享。
Scribble Diffusion 是一個簡單的線上服務,它使用 AI 將粗略的草圖轉換為精緻的影像,每一張影像都是不同的(而且沒有版權困擾)。簡單來說,我們只需要「用畫筆描繪一張草圖,在輸入描述後稍等片刻」,隨後就會為你生成一幅畫。這幅畫可以多次生成,每次生成的結果也都大不相同。
Scribble Diffusion 的能力大概是這樣的(左邊是我畫的,右邊是 TA 畫的)
a photo of grassland with cloud(有云朵的草地) the sun setting behind the mountains(山後落日) A lovely kitten(小貓咪呀)
我發現 Scribble Diffusion 作畫的能力非常出乎意料,而且可以根據你的描述來定義不同的照片風格(比如照片,油畫,素描等等),於是就產生了把這個AI 畫圖小程式內嵌到公司App中的想法。另外把小程式內嵌App是透過 FinClip 容器技術實現的。(畢竟開箱即用,也不需要做什麼配置)。
調研官網之後發現官網中的元素非常簡單,正因如此,我覺得把「Scribble Diffusion」搬運到 小程式裡大概要分這樣幾步:
- 使用 canvas 實現畫板,能夠在小程式中進行繪畫;
- 提供輸入框與生成按鈕,能夠補充圖片的描述和生成的按鈕;
- 獲取生成的圖片連結進行展示;
像那些如何寫程式碼,賬號註冊和建立小程式的流程,各位看官可以看這裡:
看了這篇文章,即使讓我現在就從頭寫一個能夠正常執行的小程式,也沒有原本想象中的那麼難了。
使用小程式實現畫板
我們可以使用小程式來實現一個畫板,使用 canvas 標籤實現畫筆功能。使用者可以在畫板上繪製畫作,也可以選擇清空畫板操作。
下面是一個示例程式碼:
<!--畫布區域--> <view> <canvas id="myCanvas" canvas-id="myCanvas" disable-scroll="false" bindtouchstart="touchStart" bindtouchmove="touchMove" bindtouchend="touchEnd"> </canvas> </view> <view bindtap="reset"> 清空畫板 </view>
Page({ data: { isProcessing: false, prompt: '', scribble: null, pen : 2, //畫筆粗細預設值 color : '#000000', // 畫筆顏色預設值 result: null, text: '' }, startX: 0, //儲存X座標軸變數 startY: 0, //儲存X座標軸變數 onLoad(params) { wx.createSelectorQuery().select('#myCanvas').context((res) => { this.context = res.context }).exec() }, //手指觸控動作開始 touchStart: function (e) { //得到觸控點的座標 this.startX = e.changedTouches[0].x this.startY = e.changedTouches[0].y // this.context = wx.createContext() this.context.setStrokeStyle(this.data.color) this.context.setLineWidth(this.data.pen) this.context.setLineCap('round') // 讓線條圓潤 this.context.beginPath() }, //手指觸控後移動 touchMove: function (e) { var startX1 = e.changedTouches[0].x var startY1 = e.changedTouches[0].y this.context.moveTo(this.startX, this.startY) this.context.lineTo(startX1, startY1) this.context.stroke() this.startX = startX1; this.startY = startY1; //只是一個記錄方法呼叫的容器,用於生成記錄繪製行為的actions陣列。context跟<canvas/>不存在對應關係,一個context生成畫布的繪製動作陣列可以應用於多個<canvas/> wx.drawCanvas({ canvasId: 'myCanvas', reserve: true, actions: this.context.getActions() // 獲取繪圖動作陣列 }) }, //手指觸控動作結束 touchEnd: function () { var imageData = wx.canvasGetImageData({ canvasId: 'myCanvas', height: 250, width: 250, x: 0, y: 0, success(res){ return res.data } }) }, //清除畫板 reset: function(){ this.context.clearRect(0, 0, 400, 400); this.context.draw(true) } })
提供輸入框和生成按鈕
我們需要提供一個 input 輸入框,供使用者輸入 prompt;同時,我們需要提供一個按鈕,點選時會觸發響應事件,將 canvas 內容生成圖片,同時將 prompt 輸入作為引數,提交給服務端進行圖片生成。
這裡是示例程式碼:
<!-- 輸入框 --> <view> <view> <input type="text" name="go" placeholder="用關鍵詞描述畫的內容" bindinput="update"/> </view> </view>
Page({ ... 省略上述程式碼 // 更新表單提交按鈕狀態 update(e){ this.setData({ prompt : e.detail.value }) }, })
獲取生成的圖片連結並展示
當使用者點選生成圖片按鈕後,我們會將 canvas 內容和使用者輸入的 prompt 作為引數提交給服務端進行圖片生成。服務端會返回生成的圖片連結,我們需要將它展示給使用者。
在下面的示例程式碼中,我們服務端傳送 POST 請求,然後解析返回的 JSON 資料,獲取圖片連結,並將其新增到頁面中。使用者就可以看到生成的圖片了。
<!-- 繪圖結果 --> <view wx:if="{{result}}"> <view> <view> <image src="{{result}}" mode="aspectFit" /> </view> <view> <view bindtap="download"> 下載 </view> </view> </view> </view>
Page({ ... 省略上述程式碼 async getCanvasImage() { return new Promise((resolve, reject) => { wx.canvasToTempFilePath({ x: 0, y: 0, width: 250, height: 250, destWidth: 250, destHeight: 250, canvasId: 'myCanvas', success(res) { console.log(res.tempFilePath) resolve(res.tempFilePath) }, fail(err) { console.log(err) } }) }) }, async upload(image) { return new Promise((resolve) => { wx.uploadFile({ url: 'xxxxxx', filePath: image, name: 'file', success (res){ const data = JSON.parse(res.data) resolve(data.url) }, fail(err){ console.log('上傳失敗') console.log(err) } }) }) }, async sleep(time) { return new Promise((resolve) => { setTimeout(() => { resolve() }, time) }) }, async handleSubmit(e) { if (!this.data.prompt) { return } wx.showLoading({ title: '生成中', }) try { const prompt = this.data.prompt const image = await this.getCanvasImage() this.setData({ error: null, isProcessing: true }); const url = await this.upload(image) console.log('圖片', url) const body = { prompt: prompt, image: url, }; const response = await my_fetch.fetch( { url: "{ "Content-Type": "application/json", }, params: JSON.stringify(body), }); let prediction = response.data; console.log('預測', prediction) if (response.statusCode !== 201) { wx.showToast({ title: '生成失敗', duration: 2000 }) this.setData({ error: '生成失敗' }); return; } while ( prediction.status !== "succeeded" && prediction.status !== "failed" ) { console.log(prediction.status) await this.sleep(500); const response = await my_fetch.fetch({ url:"}); prediction = response.data; if (response.statusCode !== 200) { this.setData({ error: prediction.detail }); return; } } if (Array.isArray(prediction.output) && prediction.output.length > 1) { wx.hideLoading() this.setData({ isProcessing: false, result: prediction.output[1] }); } else { wx.hideLoading() wx.showToast({ title: '生成失敗', duration: 2000 }) this.setData({ isProcessing: false, error: '生成失敗' }) } } catch (error) { wx.hideLoading() console.log(error) wx.showToast({ title: '生成失敗', duration: 2000 }) } }, })
生成完小程式之後,再透過 FinClip 上傳小程式就可以在 App 獲得畫板功能啦!我把這個小程式上傳到了 中,你可以掃描下方的二維碼隨意體驗,總的來說,還是挺好玩的。
如果你對小程式與 AI 的結合有什麼奇思妙想,歡迎留言探討!
當然,如果你對
有更多奇怪的想法想付諸實踐,開發者也已經將專案檔案進行了開源,歡迎嘗試~
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70017183/viewspace-2945016/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 如何在移動應用中整合美顏SDK實現人臉識別和美化功能
- 「React」如何在React中優雅的實現動畫React動畫
- 如何在直播應用中實現多人KTV?
- 如何在 UE4 移動端中實現 HZB?
- Flutter進階:在應用中實現 Hero(飛行) 動畫Flutter動畫
- H5移動端彈幕動畫實現H5動畫
- 如何在 Java 中實現無向圖Java
- jQuery中動畫的實現jQuery動畫
- 移動機器人如何在陌生環境中實現智慧導航?機器人
- 如何在 pyqt 中使用動畫實現平滑滾動的 QScrollAreaQT動畫
- Flutter動畫:用Flutter來實現一個拍手動畫Flutter動畫
- 如何在我的應用啟動介面實現「開屏廣告」?
- 新移動框架中企業自建應用的來源是【移動輕應用管理】框架
- 玩家角色——移動功能和動畫藍圖動畫
- 用 Promise + 遞迴實現灌酒動畫Promise遞迴動畫
- 100行程式碼實現HarmonyOS“畫圖”應用,eTS開發走起!行程
- 圖資料庫在中國移動金融風控的落地應用資料庫
- 深入解析Spring AI框架:在Java應用中實現智慧化互動的關鍵SpringAI框架Java
- 如何在 Kubernetes 中實現應用的無損上線和下線
- 如何在Unity中實現水體互動?Unity
- 動畫利器-lottie在懂表帝App中的實戰應用動畫APP
- SVG動畫應用-酷炫的圖片展示效果SVG動畫
- H5移動端獲獎無縫滾動動畫實現H5動畫
- 原生JS實現輪播圖--第二章動畫實現JS動畫
- SVG圖片在移動端的應用解決方案SVG
- 華為雲中國行2018·武漢站 AI上如畫江城AI
- 如何在.NET電子表格應用程式中建立流程圖流程圖
- 移動應用變現AdMob入門指南(上)
- CSS3中用background-image實現粒子動畫效果CSSS3動畫
- 用文字“畫出”時序圖:用 AI+Mermaid.js 解決互動過程中的問題時序圖AIJS
- Flutter實現動畫Flutter動畫
- Android 動畫實現Android動畫
- 如何在移動端資料視覺化大屏實現分析?視覺化
- 5分鐘用動效工廠實現粒子動畫動畫
- 安卓移動應用程式碼安全加固系統設計及實現安卓
- 移動端輪播圖實現方法(dGun.js)JS
- 計算機圖形學(CG技術)在日本動畫製作中的應用計算機動畫
- Canvas 實現畫中畫動畫效果–網易娛樂年度盤點H5動畫解密Canvas動畫H5解密