support some Edit Image
This commit is contained in:
parent
db308fe42b
commit
1c4932d005
@ -7,6 +7,8 @@ import (
|
||||
_ "apigo.cc/ai/huoshan"
|
||||
"apigo.cc/gojs"
|
||||
_ "apigo.cc/gojs/console"
|
||||
_ "apigo.cc/gojs/file"
|
||||
_ "apigo.cc/gojs/util"
|
||||
"github.com/ssgo/u"
|
||||
)
|
||||
|
||||
|
17
ai_test.js
17
ai_test.js
@ -1,8 +1,10 @@
|
||||
import co from 'apigo.cc/gojs/console'
|
||||
import file from 'apigo.cc/gojs/file'
|
||||
import u from 'apigo.cc/gojs/util'
|
||||
import ai from 'apigo.cc/ai'
|
||||
|
||||
let r = ai.huoshan.fastAsk('用一句话为你的主人写一段生成在山顶喝咖啡的图片的提示词', co.print, {
|
||||
systemPrompt: '你的主人很美丽,喜欢戴帽子'
|
||||
systemPrompt: '你的主人是个年轻姑娘,很美丽,喜欢戴帽子'
|
||||
})
|
||||
co.println()
|
||||
co.info('生成的提示词:', r.result)
|
||||
@ -16,9 +18,20 @@ let r2 = ai.huoshan.makeImage({
|
||||
co.info('生成的图片:', r2.results[0])
|
||||
|
||||
let r3 = ai.huoshan.makeImageKeepIP({
|
||||
prompt: '女孩,骑马在草原上狂奔,天上的云朵,有太阳,有小鸟',
|
||||
prompt: '年轻姑娘,表情悲伤,骑马在草原上狂奔,天上的云朵,有太阳,有小鸟',
|
||||
width: 1280,
|
||||
height: 720,
|
||||
ref: [r2.results[0]],
|
||||
})
|
||||
co.info('生成角色一致的图片:', r3.results[0])
|
||||
|
||||
let r3s = ai.huoshan.changeEmotion(r3.results[0], { target_emotion: 'liwo' })
|
||||
co.info('梨涡笑:', r3s.result)
|
||||
|
||||
let r3p = ai.huoshan.makeFacePretty(r3s.result)
|
||||
file.write('test.jpg', u.unBase64(r3p.result))
|
||||
co.info('美颜后:', 'test.jpg')
|
||||
|
||||
let r4 = ai.huoshan.getHumanSegment(r3p.result)
|
||||
file.write('test_mask.jpg', u.unBase64(r4.result))
|
||||
co.info('角色主体:', 'test_mask.jpg')
|
||||
|
@ -18,10 +18,17 @@ func init() {
|
||||
EmbeddingConfigs: defaultConf.Embedding,
|
||||
ImageConfigs: defaultConf.Image,
|
||||
VideoConfigs: defaultConf.Video,
|
||||
EditConfigs: defaultConf.Edit,
|
||||
AsrConfigs: defaultConf.Asr,
|
||||
TtsConfigs: defaultConf.Tts,
|
||||
Chat: Chat,
|
||||
Embedding: Embedding,
|
||||
MakeImage: MakeImage,
|
||||
// MakeVideo: MakeVideo,
|
||||
// GetVideoResult: GetVideoResult,
|
||||
Edit: Edit,
|
||||
// Scan: Scan,
|
||||
// Asr: Asr,
|
||||
// Tts: Tts,
|
||||
})
|
||||
}
|
||||
|
96
default.yml
96
default.yml
@ -6,58 +6,80 @@ image:
|
||||
width: 1024
|
||||
height: 1024
|
||||
makeImageHD:
|
||||
model: "high_aes_general_v20_L:general_v2.0_L"
|
||||
model: high_aes_general_v20_L:general_v2.0_L
|
||||
width: 512
|
||||
height: 512
|
||||
extra:
|
||||
req_schedule_conf: general_v20_9B_rephraser
|
||||
use_sr: true
|
||||
use_pre_llm: true
|
||||
makeCartoon:
|
||||
model: high_aes:anime_v1.3.1
|
||||
width: 1024
|
||||
height: 1024
|
||||
extra:
|
||||
req_schedule_conf: general_v20_9B_rephraser
|
||||
use_sr: true
|
||||
use_pre_llm: true
|
||||
makeImageKeepIP:
|
||||
model: "high_aes_general_v14_ip_keep:general_v1.4_ip"
|
||||
model: high_aes_general_v14_ip_keep:general_v1.4_ip
|
||||
width: 1024
|
||||
height: 1024
|
||||
makeAmericanComics:
|
||||
model: "img2img_photoverse_american_comics"
|
||||
model: img2img_photoverse_american_comics
|
||||
make3DWeird:
|
||||
model: "img2img_photoverse_3d_weird"
|
||||
model: img2img_photoverse_3d_weird
|
||||
makeCyberpunk:
|
||||
model: "img2img_photoverse_cyberpunk"
|
||||
model: img2img_photoverse_cyberpunk
|
||||
makeBabi:
|
||||
model: "img2img_xiezhen_babi_niuzai"
|
||||
model: img2img_xiezhen_babi_niuzai
|
||||
extra:
|
||||
beautify_info:
|
||||
whitening: 2
|
||||
dermabrasion: 2
|
||||
makeIDPhoto:
|
||||
model: "img2img_photoverse_executive_ID_photo"
|
||||
# ModelDoubaoLite4k = "Doubao-lite-4k"
|
||||
# ModelDoubaoLite32k = "Doubao-lite-32k"
|
||||
# ModelDoubaoLite128k = "Doubao-lite-128k"
|
||||
# ModelDoubaoPro4k = "Doubao-pro-4k"
|
||||
# ModelDoubaoPro32k = "Doubao-pro-32k"
|
||||
# ModelDoubaoPro128k = "Doubao-pro-128k"
|
||||
# ModelDoubaoPro256k = "Doubao-pro-256k"
|
||||
# ModelDoubaoEmbedding = "Doubao-embedding"
|
||||
# ModelDoubaoEmbeddingLarge = "Doubao-embedding-large"
|
||||
# ModelT2I2L = "high_aes_general_v20_L:general_v2.0_L"
|
||||
# ModelT2I2S = "high_aes_general_v20:general_v2.0"
|
||||
# ModelT2IXL = "t2i_xl_sft"
|
||||
# ModelI2IXL = "i2i_xl_sft"
|
||||
# ModelT2I14 = "high_aes_general_v14"
|
||||
# ModelI2I14IP = "high_aes_general_v14_ip_keep"
|
||||
# ModelAnime13 = "high_aes:anime_v1.3"
|
||||
# ModelAnime131 = "high_aes:anime_v1.3.1"
|
||||
# ModelPhotoverseAmericanComics = "img2img_photoverse_american_comics" // 美漫风格
|
||||
# ModelPhotoverseExecutiveIDPhoto = "img2img_photoverse_executive_ID_photo" // 商务证件照
|
||||
# ModelPhotoverse3dWeird = "img2img_photoverse_3d_weird" // 3d人偶
|
||||
# ModelPhotoverseCyberpunk = "img2img_photoverse_cyberpunk" // 赛博朋克
|
||||
# ModelXiezhenGubao = "img2img_xiezhen_gubao" // 古堡
|
||||
# ModelXiezhenBabiNiuzai = "img2img_xiezhen_babi_niuzai" // 芭比牛仔
|
||||
# ModelXiezhenBathrobe = "img2img_xiezhen_bathrobe" // 浴袍风格
|
||||
# ModelXiezhenButterflyMachin = "img2img_xiezhen_butterfly_machin" // 蝴蝶机械
|
||||
# ModelXiezhenZhichangzhengjianzhao = "img2img_xiezhen_zhichangzhengjianzhao" // 职场证件照
|
||||
# ModelXiezhenChristmas = "img2img_xiezhen_christmas" // 圣诞
|
||||
# ModelXiezhenDessert = "img2img_xiezhen_dessert" // 美式甜点师
|
||||
# ModelXiezhenOldMoney = "img2img_xiezhen_old_money" // old money
|
||||
# ModelXiezhenSchool = "img2img_xiezhen_school" // 最美校园
|
||||
model: img2img_photoverse_executive_ID_photo
|
||||
makeOutpainting:
|
||||
model: i2i_outpainting
|
||||
make3DStyle:
|
||||
model: img2img_disney_3d_style
|
||||
makeCartoonStyle:
|
||||
model: img2img_cartoon_style
|
||||
edit:
|
||||
getHumanSegment:
|
||||
action: HumanSegment
|
||||
refine: 1
|
||||
return_foreground_image: 1
|
||||
changeEmotion:
|
||||
action: EmotionPortrait
|
||||
# jiuwo: 酒窝笑
|
||||
# liwo: 梨窝笑
|
||||
# big_smile_white_teeth: 露牙大笑
|
||||
# classic_white_teeth: 露牙标准笑
|
||||
# cool: 耍酷
|
||||
# sad: 悲伤
|
||||
# tight_smile: 勉强笑
|
||||
target_emotion: big_smile_white_teeth
|
||||
changeHair:
|
||||
action: EmotionPortrait
|
||||
# 101: 刘海(默认)
|
||||
# 201: 长发
|
||||
# 301: 刘海加长发
|
||||
# 401: 中程度增发
|
||||
# 402: 轻程度增发
|
||||
# 403: 重程度增发
|
||||
# 502: 轻程度卷发
|
||||
# 503: 重程度卷发
|
||||
# 603: 短发(要求输入尺寸<2048x2048,若输入大于2048x2048的图片,输出的图片会被resize成最长边2048;)
|
||||
# 801: 金发
|
||||
# 901: 直发
|
||||
# 1001: 头发去油(轻微效果,原图中此问题建议较为明显)
|
||||
# 1101: 补发际线(调整过高的发际线,轻微效果,原图中此问题建议较为明显)
|
||||
# 1201: 头发柔顺 (轻微效果,原图需有较大发型区域,原图中此问题建议较为明显)
|
||||
# 1301: 补发缝(轻微效果,填补头发区域中的头皮部分,原图中此问题建议较为明显)
|
||||
hair_type: 101
|
||||
makeFacePretty:
|
||||
action: FacePretty
|
||||
do_risk: false
|
||||
multi_face: 1
|
||||
beauty_level: 1
|
||||
|
114
gc.go
114
gc.go
@ -2,6 +2,7 @@ package huoshan
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@ -86,6 +87,11 @@ func MakeImage(aiConf *ai.AIConfig, conf ai.ImageConfig) (ai.ImageResult, error)
|
||||
if conf.Sref > 0 {
|
||||
data["ref_ip_weight"] = conf.Sref
|
||||
}
|
||||
} else if strings.Contains(conf.Model, ":anime_") {
|
||||
// 动漫模型
|
||||
if conf.Sref > 0 {
|
||||
data["strength"] = conf.Sref
|
||||
}
|
||||
} else {
|
||||
// 图生图模型
|
||||
style_reference_args := map[string]any{"binary_data_index": 0}
|
||||
@ -125,3 +131,111 @@ func MakeImage(aiConf *ai.AIConfig, conf ai.ImageConfig) (ai.ImageResult, error)
|
||||
UsedTime: t2,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func Edit(aiConf *ai.AIConfig, from string, conf map[string]any) (ai.StringResult, error) {
|
||||
action := u.String(conf["action"])
|
||||
c := getVisualClient(aiConf)
|
||||
t1 := time.Now().UnixMilli()
|
||||
switch action {
|
||||
case "EmotionPortrait":
|
||||
// 修改表情
|
||||
req := map[string]any{"req_key": "emotion_portrait", "return_url": true}
|
||||
for k, v := range conf {
|
||||
if k != "action" {
|
||||
req[k] = v
|
||||
}
|
||||
}
|
||||
if strings.Contains(from, "://") {
|
||||
req["image_urls"] = []string{from}
|
||||
} else {
|
||||
req["binary_data_base64"] = []string{from}
|
||||
}
|
||||
resp, status, err := c.EmotionPortrait(req)
|
||||
if err != nil {
|
||||
return ai.StringResult{}, err
|
||||
}
|
||||
if status != 200 {
|
||||
return ai.StringResult{}, errors.New(u.String(resp.Message))
|
||||
}
|
||||
result := resp.Data.ImageUrls[0]
|
||||
return ai.StringResult{
|
||||
Result: result,
|
||||
UsedTime: time.Now().UnixMilli() - t1,
|
||||
}, nil
|
||||
case "HumanSegment":
|
||||
// 抠出人像
|
||||
req := url.Values{
|
||||
"refine": {u.String(u.Int(conf["refine"]))},
|
||||
"return_foreground_image": {u.String(u.Int(conf["return_foreground_image"]))},
|
||||
}
|
||||
if strings.Contains(from, "://") {
|
||||
req["image_url"] = []string{from}
|
||||
} else {
|
||||
req["image_base64"] = []string{from}
|
||||
}
|
||||
resp, status, err := c.HumanSegment(req)
|
||||
if err != nil {
|
||||
return ai.StringResult{}, err
|
||||
}
|
||||
if status != 200 {
|
||||
return ai.StringResult{}, errors.New(u.String(resp.Message))
|
||||
}
|
||||
// u.WriteFileBytes("mask.jpg", u.UnBase64(resp.Data.Mask))
|
||||
// u.WriteFileBytes("body.jpg", u.UnBase64(resp.Data.ForegroundImage))
|
||||
result := resp.Data.ForegroundImage
|
||||
if result == "" {
|
||||
result = resp.Data.Mask
|
||||
}
|
||||
return ai.StringResult{
|
||||
Result: result,
|
||||
UsedTime: time.Now().UnixMilli() - t1,
|
||||
}, nil
|
||||
case "FacePretty":
|
||||
// 美颜
|
||||
req := url.Values{
|
||||
"do_risk": {u.GetUpperName(u.String(u.Bool(conf["do_risk"])))},
|
||||
"multi_face": {u.String(u.Int(conf["multi_face"]))},
|
||||
"beauty_level": {u.String(u.Float(conf["beauty_level"]))},
|
||||
}
|
||||
if strings.Contains(from, "://") {
|
||||
req["image_url"] = []string{from}
|
||||
} else {
|
||||
req["image_base64"] = []string{from}
|
||||
}
|
||||
resp, status, err := c.FacePretty(req)
|
||||
if err != nil {
|
||||
return ai.StringResult{}, err
|
||||
}
|
||||
if status != 200 {
|
||||
return ai.StringResult{}, errors.New(u.String(resp.Message))
|
||||
}
|
||||
return ai.StringResult{
|
||||
Result: resp.Data.Image,
|
||||
UsedTime: time.Now().UnixMilli() - t1,
|
||||
}, nil
|
||||
case "HairStyle":
|
||||
// 改变发型
|
||||
req := url.Values{
|
||||
"req_key": {"hair_style"},
|
||||
"return_url": {"true"},
|
||||
"hair_type": {u.String(conf["hair_type"])},
|
||||
}
|
||||
if strings.Contains(from, "://") {
|
||||
req["image_urls"] = []string{from}
|
||||
} else {
|
||||
req["binary_data_base64"] = []string{from}
|
||||
}
|
||||
resp, status, err := c.HairStyle(req)
|
||||
if err != nil {
|
||||
return ai.StringResult{}, err
|
||||
}
|
||||
if status != 200 {
|
||||
return ai.StringResult{}, errors.New(u.String(resp.Message))
|
||||
}
|
||||
return ai.StringResult{
|
||||
Result: resp.Data.Image,
|
||||
UsedTime: time.Now().UnixMilli() - t1,
|
||||
}, nil
|
||||
}
|
||||
return ai.StringResult{}, nil
|
||||
}
|
||||
|
10
go.mod
10
go.mod
@ -1,13 +1,13 @@
|
||||
module apigo.cc/ai/huoshan
|
||||
|
||||
go 1.22
|
||||
|
||||
toolchain go1.22.1
|
||||
go 1.18
|
||||
|
||||
require (
|
||||
apigo.cc/ai v0.0.1
|
||||
apigo.cc/ai v0.0.2
|
||||
apigo.cc/gojs v0.0.4
|
||||
apigo.cc/gojs/console v0.0.1
|
||||
apigo.cc/gojs/file v0.0.2
|
||||
apigo.cc/gojs/util v0.0.3
|
||||
github.com/ssgo/u v1.7.9
|
||||
github.com/volcengine/volc-sdk-golang v1.0.182
|
||||
github.com/volcengine/volcengine-go-sdk v1.0.162
|
||||
@ -24,7 +24,7 @@ require (
|
||||
github.com/dlclark/regexp2 v1.11.4 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible // indirect
|
||||
github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect
|
||||
github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/ssgo/config v1.7.8 // indirect
|
||||
|
Loading…
Reference in New Issue
Block a user