[fix] encoding images

This commit is contained in:
kwaroran
2023-11-18 04:05:49 +09:00
parent d69c8eb6b6
commit 37455894dc
4 changed files with 33 additions and 28 deletions

View File

@@ -1,5 +1,5 @@
import { get, writable, type Writable } from "svelte/store" import { get, writable, type Writable } from "svelte/store"
import { alertConfirm, alertError, alertMd, alertNormal, alertSelect, alertStore, alertTOS } from "./alert" import { alertConfirm, alertError, alertMd, alertNormal, alertSelect, alertStore, alertTOS, alertWait } from "./alert"
import { DataBase, defaultSdDataFunc, type character, setDatabase, type customscript, type loreSettings, type loreBook, type triggerscript } from "./storage/database" import { DataBase, defaultSdDataFunc, type character, setDatabase, type customscript, type loreSettings, type loreBook, type triggerscript } from "./storage/database"
import { checkNullish, selectMultipleFile, sleep } from "./util" import { checkNullish, selectMultipleFile, sleep } from "./util"
import { language } from "src/lang" import { language } from "src/lang"
@@ -10,6 +10,7 @@ import { cloneDeep } from "lodash"
import { selectedCharID } from "./stores" import { selectedCharID } from "./stores"
import { convertImage } from "./parser" import { convertImage } from "./parser"
import * as yuso from 'yuso' import * as yuso from 'yuso'
import { reencodeImage } from "./image"
export const hubURL = "https://sv.risuai.xyz" export const hubURL = "https://sv.risuai.xyz"
@@ -68,7 +69,7 @@ async function importCharacterProcess(f:{
} }
} }
const charaData:OldTavernChar = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8')) const charaData:OldTavernChar = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8'))
const imgp = await saveAsset(yuso.trim(img)) const imgp = await saveAsset(await reencodeImage(img))
let db = get(DataBase) let db = get(DataBase)
db.characters.push(convertOldTavernAndJSON(charaData, imgp)) db.characters.push(convertOldTavernAndJSON(charaData, imgp))
DataBase.set(db) DataBase.set(db)
@@ -105,6 +106,7 @@ export async function characterURLImport() {
const charPath = (new URLSearchParams(location.search)).get('charahub') const charPath = (new URLSearchParams(location.search)).get('charahub')
try { try {
if(charPath){ if(charPath){
alertWait('Loading from Chub...')
const url = new URL(location.href); const url = new URL(location.href);
url.searchParams.delete('charahub'); url.searchParams.delete('charahub');
window.history.pushState(null, '', url.toString()); window.history.pushState(null, '', url.toString());
@@ -120,26 +122,10 @@ export async function characterURLImport() {
} }
}) })
const img = new Uint8Array(await chara.arrayBuffer()) const img = new Uint8Array(await chara.arrayBuffer())
await importCharacterProcess({
const readed = (yuso.decode(img, "chara")) name: 'charahub.png',
{ data: img
const charaData:CharacterCardV2 = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8')) })
if(await importSpecv2(charaData, img)){
checkCharOrder()
return
}
}
{
const imgp = await saveAsset(yuso.trim(img))
let db = get(DataBase)
const charaData:OldTavernChar = JSON.parse(Buffer.from(readed, 'base64').toString('utf-8'))
db.characters.push(convertOldTavernAndJSON(charaData, imgp))
DataBase.set(db)
checkCharOrder()
alertNormal(language.importedCharacter)
return
}
} }
} catch (error) { } catch (error) {
alertError(language.errors.noData) alertError(language.errors.noData)
@@ -221,7 +207,7 @@ async function importSpecv2(card:CharacterCardV2, img?:Uint8Array, mode?:'hub'|'
} }
const data = card.data const data = card.data
const im = img ? await saveAsset(yuso.trim(img)) : undefined const im = img ? await saveAsset(await reencodeImage(img)) : undefined
let db = get(DataBase) let db = get(DataBase)
const risuext = cloneDeep(data.extensions.risuai) const risuext = cloneDeep(data.extensions.risuai)
@@ -513,6 +499,7 @@ export async function exportSpecV2(char:character, type:'png'|'json' = 'png') {
await sleep(10) await sleep(10)
img = await reencodeImage(img)
img = yuso.encode(img, "chara",Buffer.from(JSON.stringify(card)).toString('base64')) img = yuso.encode(img, "chara",Buffer.from(JSON.stringify(card)).toString('base64'))
alertStore.set({ alertStore.set({

View File

@@ -8,6 +8,7 @@ import { v4 as uuidv4 } from 'uuid';
import { selectedCharID } from "./stores"; import { selectedCharID } from "./stores";
import { checkCharOrder, downloadFile, getFileSrc, readImage } from "./storage/globalApi"; import { checkCharOrder, downloadFile, getFileSrc, readImage } from "./storage/globalApi";
import * as yuso from 'yuso' import * as yuso from 'yuso'
import { reencodeImage } from "./image";
export function createNewCharacter() { export function createNewCharacter() {
let db = get(DataBase) let db = get(DataBase)
@@ -71,13 +72,13 @@ export async function getCharImage(loc:string, type:'plain'|'css'|'contain'|'lgc
} }
export async function selectCharImg(charId:number) { export async function selectCharImg(charId:number) {
const selected = await selectSingleFile(['png']) const selected = await selectSingleFile(['png', 'webp', 'gif', 'jpg', 'jpeg'])
if(!selected){ if(!selected){
return return
} }
const img = selected.data const img = selected.data
let db = get(DataBase) let db = get(DataBase)
const imgp = await saveImage(img) const imgp = await saveImage(await reencodeImage(img))
db.characters[charId].image = imgp db.characters[charId].image = imgp
setDatabase(db) setDatabase(db)
} }
@@ -492,7 +493,7 @@ export async function addDefaultCharacters() {
} }
char.chatPage = 0 char.chatPage = 0
char.image = await saveImage(yuso.trim(Buffer.from(imgBuffer))) char.image = await saveImage(await reencodeImage(Buffer.from(imgBuffer)))
char.chaId = uuidv4() char.chaId = uuidv4()
db.characters.push(characterFormatUpdate(char)) db.characters.push(characterFormatUpdate(char))
setDatabase(db) setDatabase(db)

View File

@@ -86,4 +86,20 @@ export async function getInlayImage(id: string){
export function supportsInlayImage(){ export function supportsInlayImage(){
const db = get(DataBase) const db = get(DataBase)
return db.aiModel.startsWith('gptv') || (db.aiModel === 'reverse_proxy' && db.proxyRequestModel?.startsWith('gptv')) return db.aiModel.startsWith('gptv') || (db.aiModel === 'reverse_proxy' && db.proxyRequestModel?.startsWith('gptv'))
}
export async function reencodeImage(img:Uint8Array){
const canvas = document.createElement('canvas')
const imgObj = new Image()
imgObj.src = URL.createObjectURL(new Blob([img], {type: `image/png`}))
await imgObj.decode()
let drawHeight = imgObj.height
let drawWidth = imgObj.width
canvas.width = drawWidth
canvas.height = drawHeight
const ctx = canvas.getContext('2d')
ctx.drawImage(imgObj, 0, 0, drawWidth, drawHeight)
const b64 = canvas.toDataURL('image/png').split(',')[1]
const b = Buffer.from(b64, 'base64')
return b
} }

View File

@@ -6,6 +6,7 @@ import * as yuso from 'yuso'
import { downloadFile, readImage } from "./storage/globalApi" import { downloadFile, readImage } from "./storage/globalApi"
import { language } from "src/lang" import { language } from "src/lang"
import { cloneDeep } from "lodash" import { cloneDeep } from "lodash"
import { reencodeImage } from "./image"
export async function selectUserImg() { export async function selectUserImg() {
const selected = await selectSingleFile(['png']) const selected = await selectSingleFile(['png'])
@@ -80,7 +81,7 @@ export async function exportUserPersona(){
await sleep(10) await sleep(10)
img = yuso.encode(yuso.trim(img), "persona",Buffer.from(JSON.stringify(card)).toString('base64')) img = yuso.encode(await reencodeImage(img), "persona",Buffer.from(JSON.stringify(card)).toString('base64'))
alertStore.set({ alertStore.set({
type: 'wait', type: 'wait',
@@ -102,7 +103,7 @@ export async function importUserPersona(){
let db = get(DataBase) let db = get(DataBase)
db.personas.push({ db.personas.push({
name: data.name, name: data.name,
icon: await saveImage(yuso.trim(v.data)), icon: await saveImage(await reencodeImage(v.data)),
personaPrompt: data.personaPrompt personaPrompt: data.personaPrompt
}) })
setDatabase(db) setDatabase(db)