Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
T
text2video-frontend
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
周成波
text2video-frontend
Commits
ee1cdc60
Commit
ee1cdc60
authored
Apr 03, 2024
by
Administrator
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
增加局部重绘
parent
f69ff7a9
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
360 additions
and
10 deletions
+360
-10
text2videoService.ts
src/api/service/text2videoService.ts
+57
-6
index.vue
src/views/home/index.vue
+303
-4
No files found.
src/api/service/text2videoService.ts
View file @
ee1cdc60
...
@@ -31,12 +31,12 @@ export default {
...
@@ -31,12 +31,12 @@ export default {
img_idx
:
string
=
""
,
img_idx
:
string
=
""
,
prompt
:
string
=
""
,
prompt
:
string
=
""
,
negative_prompt
:
string
=
""
,
negative_prompt
:
string
=
""
,
width
:
string
=
"
960
"
,
width
:
string
=
""
,
height
:
string
=
"
512
"
,
height
:
string
=
""
,
sampler_index
:
string
=
"
DPM++ 2M Karras
"
,
sampler_index
:
string
=
""
,
seed
:
string
=
"
-1
"
,
seed
:
string
=
""
,
steps
:
string
=
"
25
"
,
steps
:
string
=
""
,
cfg_scale
:
string
=
"
9
"
,
cfg_scale
:
string
=
""
,
encrypt
:
string
=
"false"
,
encrypt
:
string
=
"false"
,
model
:
string
=
""
model
:
string
=
""
):
Promise
<
{
"domain_image_path"
:
string
,
"local_image_path"
:
string
}
>
{
):
Promise
<
{
"domain_image_path"
:
string
,
"local_image_path"
:
string
}
>
{
...
@@ -73,6 +73,57 @@ export default {
...
@@ -73,6 +73,57 @@ export default {
});
});
},
},
submitSDInPaint
(
task_id
:
string
=
""
,
img_idx
:
string
=
""
,
prompt
:
string
=
""
,
negative_prompt
:
string
=
""
,
width
:
string
=
""
,
height
:
string
=
""
,
sampler_index
:
string
=
""
,
seed
:
string
=
""
,
steps
:
string
=
""
,
cfg_scale
:
string
=
""
,
encrypt
:
string
=
"false"
,
model
:
string
=
""
,
base_img
:
string
=
""
,
mask
:
string
=
""
):
Promise
<
{
"domain_image_path"
:
string
,
"local_image_path"
:
string
}
>
{
if
(
!
prompt
||
!
base_img
||
!
mask
)
{
return
Promise
.
reject
(
"SD提示词、基础图、mask均不能为空"
);
}
const
post_data
=
{
task_id
:
task_id
,
img_idx
:
img_idx
,
prompt
:
prompt
,
negative_prompt
:
negative_prompt
,
sampler_index
:
sampler_index
,
seed
:
seed
,
steps
:
steps
,
width
:
width
,
height
:
height
,
cfg_scale
:
cfg_scale
,
encrypt
:
encrypt
,
model
:
model
,
base_img
:
base_img
,
mask
:
mask
}
return
request
.
post
(
'/text2video/img2img_inpaint'
,
post_data
)
.
then
((
res
:
any
)
=>
{
// console.log(res);
if
(
res
&&
res
.
code
===
0
)
{
return
{
"domain_image_path"
:
res
.
data
.
result
.
domain_image_path
,
"local_image_path"
:
res
.
data
.
result
.
local_image_path
};
}
else
{
const
errorMessage
=
res
?
res
.
message
:
"未知错误"
;
return
Promise
.
reject
(
errorMessage
);
}
})
.
catch
((
err
:
any
)
=>
{
console
.
log
(
`err =
${
JSON
.
stringify
(
err
)}
`
);
return
Promise
.
reject
(
`与 stable-diffusion-webui Api 通讯失败`
);
});
},
submitGenVideo
(
gen_video_param
:
any
):
Promise
<
string
>
{
submitGenVideo
(
gen_video_param
:
any
):
Promise
<
string
>
{
if
(
!
gen_video_param
)
{
if
(
!
gen_video_param
)
{
return
Promise
.
reject
(
"输入不能为空"
);
return
Promise
.
reject
(
"输入不能为空"
);
...
...
src/views/home/index.vue
View file @
ee1cdc60
...
@@ -87,6 +87,13 @@ const cover_backcover = reactive({
...
@@ -87,6 +87,13 @@ const cover_backcover = reactive({
product_pic_speech
:
""
,
product_pic_speech
:
""
,
});
});
const
inPaintVisible
=
ref
(
false
);
const
inPaintBaseImgData
=
ref
(
""
);
const
inPaintMaskData
=
ref
(
""
);
const
inPaintType
=
ref
(
""
);
const
inPaintItem
=
ref
();
const
inPaintPrompt
=
ref
(
""
);
onMounted
(()
=>
{
onMounted
(()
=>
{
// 初始化task_id
// 初始化task_id
...
@@ -775,7 +782,7 @@ const onChangeScreen = (val: string) => {
...
@@ -775,7 +782,7 @@ const onChangeScreen = (val: string) => {
if
(
!
form
.
task_id
)
{
if
(
!
form
.
task_id
)
{
// 初始化task_id
// 初始化task_id
form
.
task_id
=
utils
.
genDateTimeStr
();
form
.
task_id
=
utils
.
genDateTimeStr
();
console
.
log
(
'更改屏幕设置,
重新生成
task_id='
,
form
.
task_id
)
console
.
log
(
'更改屏幕设置,task_id='
,
form
.
task_id
)
}
}
if
(
debug
.
value
==
true
)
{
if
(
debug
.
value
==
true
)
{
...
@@ -997,7 +1004,7 @@ const MarketingTemplateUploadProductPicSuccess = (val: Wm.UploadResult) => {
...
@@ -997,7 +1004,7 @@ const MarketingTemplateUploadProductPicSuccess = (val: Wm.UploadResult) => {
message
:
'上传成功'
,
message
:
'上传成功'
,
type
:
'success'
type
:
'success'
})
})
onMarketingTemplateAddTextToPic
(
'product'
);
//
onMarketingTemplateAddTextToPic('product');
}
else
{
}
else
{
ElMessage
({
ElMessage
({
message
:
'上传失败:'
+
val
.
message
,
message
:
'上传失败:'
+
val
.
message
,
...
@@ -1028,7 +1035,7 @@ const MarketingTemplateUploadCoverPicSuccess = (val: Wm.UploadResult) => {
...
@@ -1028,7 +1035,7 @@ const MarketingTemplateUploadCoverPicSuccess = (val: Wm.UploadResult) => {
message
:
'上传成功'
,
message
:
'上传成功'
,
type
:
'success'
type
:
'success'
})
})
onMarketingTemplateAddTextToPic
(
'cover'
);
//
onMarketingTemplateAddTextToPic('cover');
}
else
{
}
else
{
ElMessage
({
ElMessage
({
message
:
'上传失败:'
+
val
.
message
,
message
:
'上传失败:'
+
val
.
message
,
...
@@ -1093,7 +1100,7 @@ const onAddMarketingTemplatePicText = async (type: string, action: string, index
...
@@ -1093,7 +1100,7 @@ const onAddMarketingTemplatePicText = async (type: string, action: string, index
};
};
if
(
type
==
'product'
)
{
if
(
type
==
'product'
)
{
const
newElement
=
{
const
newElement
=
{
text
:
"关注 点赞 评论
\n
记得一键三连哦
"
,
text
:
"关注 点赞 评论"
,
color
:
"#DAFB01"
,
color
:
"#DAFB01"
,
bg_color
:
"#000000"
,
bg_color
:
"#000000"
,
font_size
:
60
,
font_size
:
60
,
...
@@ -1279,6 +1286,228 @@ const onSelectCoverChange = (value: any) => {
...
@@ -1279,6 +1286,228 @@ const onSelectCoverChange = (value: any) => {
cover_backcover
.
cover_pic_with_text_local
=
''
;
cover_backcover
.
cover_pic_with_text_local
=
''
;
onMarketingTemplateAddTextToPic
(
'cover'
);
onMarketingTemplateAddTextToPic
(
'cover'
);
}
}
// 局部重绘Dialog
const
showInPaintDialog
=
(
type
:
string
,
item
:
any
)
=>
{
let
base_img_path
=
""
;
inPaintType
.
value
=
type
;
inPaintItem
.
value
=
null
;
inPaintPrompt
.
value
=
""
;
inPaintBaseImgData
.
value
=
""
;
inPaintMaskData
.
value
=
""
;
if
(
type
==
"scene"
)
{
inPaintItem
.
value
=
item
;
inPaintPrompt
.
value
=
inPaintItem
.
value
.
场景关键词
+
' '
+
inPaintItem
.
value
.
角色关键词
;
base_img_path
=
inPaintItem
.
value
.
本镜配图
;
}
else
if
(
type
==
"cover"
)
{
inPaintPrompt
.
value
=
""
;
base_img_path
=
cover_backcover
.
cover_pic
;
}
else
if
(
type
==
'product'
)
{
inPaintPrompt
.
value
=
""
;
base_img_path
=
cover_backcover
.
product_pic
;
};
if
(
!
base_img_path
||
base_img_path
.
length
==
0
)
{
ElMessage
({
message
:
"没有基础图片,请确认"
,
type
:
"error"
,
});
return
;
}
inPaintVisible
.
value
=
true
;
// 打开对话框
// 等待元素加载完成
nextTick
(()
=>
{
// 局部重绘
const
base_canvas
=
document
.
getElementById
(
'baseCanvas'
)
as
HTMLCanvasElement
;
const
mask_canvas
=
document
.
getElementById
(
'maskCanvas'
)
as
HTMLCanvasElement
;
if
(
base_canvas
&&
mask_canvas
)
{
let
base_ctx
=
base_canvas
.
getContext
(
'2d'
)
as
CanvasRenderingContext2D
;
base_ctx
.
clearRect
(
0
,
0
,
base_canvas
.
width
,
base_canvas
.
height
);
var
img
=
new
Image
();
img
.
crossOrigin
=
'Anonymous'
;
// 如果图片需要用于跨域,则需要设置这个属性
img
.
onload
=
function
()
{
base_canvas
.
width
=
img
.
width
;
base_canvas
.
height
=
img
.
height
;
base_ctx
.
drawImage
(
img
,
0
,
0
,
base_canvas
.
width
,
base_canvas
.
height
);
};
img
.
src
=
base_img_path
;
let
mask_ctx
=
mask_canvas
.
getContext
(
'2d'
)
as
CanvasRenderingContext2D
;
mask_ctx
.
clearRect
(
0
,
0
,
mask_canvas
.
width
,
mask_canvas
.
height
);
// mask_ctx.globalAlpha = 0.5; // 可自定义透明度
let
isDrawing
=
false
;
// 鼠标或触摸事件开始绘制
mask_canvas
.
addEventListener
(
'mousedown'
,
startDrawing
);
mask_canvas
.
addEventListener
(
'touchstart'
,
startDrawing
);
// 鼠标或触摸事件绘制中
mask_canvas
.
addEventListener
(
'mousemove'
,
draw
);
mask_canvas
.
addEventListener
(
'touchmove'
,
draw
);
// 鼠标或触摸事件结束绘制
mask_canvas
.
addEventListener
(
'mouseup'
,
stopDrawing
);
mask_canvas
.
addEventListener
(
'touchend'
,
stopDrawing
);
mask_canvas
.
addEventListener
(
'mouseout'
,
stopDrawing
);
// 清除按钮点击事件
const
clearButton
=
document
.
getElementById
(
'clearButton'
)
as
HTMLButtonElement
;
clearButton
.
addEventListener
(
'click'
,
clearCanvas
);
// 开始绘制
function
startDrawing
(
e
:
any
)
{
isDrawing
=
true
;
const
{
offsetX
,
offsetY
}
=
getOffset
(
e
);
mask_ctx
.
lineWidth
=
40
;
// 设置线条粗细
// mask_ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)'; // 设置线条颜色
mask_ctx
.
strokeStyle
=
'white'
;
// 设置线条颜色
mask_ctx
.
lineCap
=
"round"
;
// 线头尾为圆形
mask_ctx
.
beginPath
();
mask_ctx
.
moveTo
(
offsetX
,
offsetY
);
}
// 绘制中
function
draw
(
e
:
any
)
{
if
(
!
isDrawing
)
return
;
const
{
offsetX
,
offsetY
}
=
getOffset
(
e
);
mask_ctx
.
lineTo
(
offsetX
,
offsetY
);
mask_ctx
.
stroke
();
}
// 结束绘制
function
stopDrawing
()
{
isDrawing
=
false
;
inPaintBaseImgData
.
value
=
base_canvas
.
toDataURL
(
'image/png'
);
inPaintMaskData
.
value
=
mask_canvas
.
toDataURL
(
'image/png'
);
}
// 清除画布
function
clearCanvas
()
{
mask_ctx
.
clearRect
(
0
,
0
,
mask_canvas
.
width
,
mask_canvas
.
height
);
}
// 获取鼠标或触摸事件的偏移量
function
getOffset
(
e
:
any
)
{
const
rect
=
mask_canvas
.
getBoundingClientRect
();
let
offsetX
,
offsetY
;
if
(
e
.
type
.
includes
(
'touch'
))
{
offsetX
=
e
.
touches
[
0
].
clientX
-
rect
.
left
;
offsetY
=
e
.
touches
[
0
].
clientY
-
rect
.
top
;
}
else
{
offsetX
=
e
.
offsetX
;
offsetY
=
e
.
offsetY
;
}
return
{
offsetX
,
offsetY
};
}
}
else
{
console
.
error
(
'Canvas element not found'
);
}
});
}
const
onSubmitInPaint
=
async
()
=>
{
if
(
!
form
.
task_id
)
{
ElMessage
({
message
:
"task_id不能为空,请刷新页面"
,
type
:
"error"
,
});
return
;
}
// console.log('333', inPaintBaseImgData.value)
// console.log('333', inPaintMaskData.value)
// return;
if
(
!
inPaintBaseImgData
.
value
||
!
inPaintMaskData
.
value
)
{
ElMessage
({
message
:
"请在图片上涂抹需要保留的部分!"
,
type
:
"error"
,
});
return
;
}
if
(
!
inPaintPrompt
.
value
||
inPaintPrompt
.
value
.
length
==
0
)
{
ElMessage
({
message
:
"请填写画面描述!"
,
type
:
"error"
,
});
return
;
}
const
sampler_index
=
sd_model
.
sampler_index
;
const
seed
=
sd_model
.
seed
;
const
steps
=
sd_model
.
steps
;
const
cfg_scale
=
sd_model
.
cfg_scale
;
const
model
=
sd_model
.
model
;
const
base_img
=
inPaintBaseImgData
.
value
;
const
mask
=
inPaintMaskData
.
value
;
let
sd_prompt
=
""
;
let
img_id
=
""
let
item
=
null
;
if
(
inPaintType
.
value
==
"scene"
)
{
item
=
inPaintItem
.
value
;
item
.
本镜配图
=
"src/assets/loading.gif"
;
img_id
=
item
.
编号
;
}
else
if
(
inPaintType
.
value
==
"cover"
)
{
img_id
=
'cover'
;
cover_backcover
.
cover_pic
=
'src/assets/waiting.png'
;
cover_backcover
.
cover_pic_local
=
''
;
}
else
if
(
inPaintType
.
value
==
'product'
)
{
img_id
=
'product'
;
cover_backcover
.
product_pic
=
'src/assets/waiting.png'
;
cover_backcover
.
product_pic_local
=
''
;
};
try
{
let
keywords_en
=
await
text2videoService
.
submitTranslateToEn
(
utils
.
aesEncrypt
(
inPaintPrompt
.
value
),
form
.
task_id
,
"true"
);
sd_prompt
=
keywords_en
.
replace
(
/"/g
,
''
)
+
","
+
sd_prompt_prefix
;
const
sd_img
=
await
text2videoService
.
submitSDInPaint
(
form
.
task_id
,
img_id
,
utils
.
aesEncrypt
(
sd_prompt
),
utils
.
aesEncrypt
(
sd_negative_prompt_prefix
),
utils
.
aesEncrypt
(
form
.
img_size
.
width
),
utils
.
aesEncrypt
(
form
.
img_size
.
height
),
utils
.
aesEncrypt
(
sampler_index
),
utils
.
aesEncrypt
(
seed
),
utils
.
aesEncrypt
(
steps
),
utils
.
aesEncrypt
(
cfg_scale
),
"true"
,
utils
.
aesEncrypt
(
model
),
utils
.
aesEncrypt
(
base_img
),
utils
.
aesEncrypt
(
mask
),
);
if
(
inPaintType
.
value
==
"scene"
)
{
item
.
本镜配图
=
sd_img
.
domain_image_path
+
"?v="
+
utils
.
genDateTimeStr
();
item
.
local_image_path
=
sd_img
.
local_image_path
;
}
else
if
(
inPaintType
.
value
==
'cover'
)
{
cover_backcover
.
cover_pic
=
sd_img
.
domain_image_path
+
"?v="
+
utils
.
genDateTimeStr
();
cover_backcover
.
cover_pic_local
=
sd_img
.
local_image_path
;
}
else
if
(
inPaintType
.
value
==
'product'
)
{
cover_backcover
.
product_pic
=
sd_img
.
domain_image_path
+
"?v="
+
utils
.
genDateTimeStr
();
cover_backcover
.
product_pic_local
=
sd_img
.
local_image_path
;
};
}
catch
(
error
)
{
ElMessage
({
message
:
String
(
error
),
type
:
"error"
,
});
}
finally
{
inPaintVisible
.
value
=
false
;
// 关闭对话框
}
}
</
script
>
</
script
>
<
template
>
<
template
>
...
@@ -1510,6 +1739,14 @@ const onSelectCoverChange = (value: any) => {
...
@@ -1510,6 +1739,14 @@ const onSelectCoverChange = (value: any) => {
>
上传图片
</el-button
>
上传图片
</el-button
>
>
</el-upload>
</el-upload>
<div
style=
"margin: 5px 0"
>
<el-button
type=
"primary"
size=
"small"
@
click=
"showInPaintDialog('scene', scope.row)"
>
局部重绘
</el-button
>
</div>
<!--
<div
style=
"margin: 5px 0"
><el-button
plain
size=
"small"
@
click=
"onClearOnePic(scope.row)"
>
清除图片
</el-button></div>
-->
<!--
<div
style=
"margin: 5px 0"
><el-button
plain
size=
"small"
@
click=
"onClearOnePic(scope.row)"
>
清除图片
</el-button></div>
-->
<div
style=
"margin: 5px 0"
>
<div
style=
"margin: 5px 0"
>
<el-button
plain
size=
"small"
@
click=
"showsdprompt(scope.row)"
<el-button
plain
size=
"small"
@
click=
"showsdprompt(scope.row)"
...
@@ -1599,6 +1836,13 @@ const onSelectCoverChange = (value: any) => {
...
@@ -1599,6 +1836,13 @@ const onSelectCoverChange = (value: any) => {
style=
"margin-left: 12px"
style=
"margin-left: 12px"
>
清除图片
</el-button
>
清除图片
</el-button
>
>
<el-button
type=
"primary"
size=
"small"
@
click=
"showInPaintDialog('cover', '')"
style=
"margin-left: 12px"
>
局部重绘
</el-button
>
</el-form-item>
</el-form-item>
<el-form-item>
<el-form-item>
<div
style=
"width: 100%"
>
<div
style=
"width: 100%"
>
...
@@ -1708,6 +1952,13 @@ const onSelectCoverChange = (value: any) => {
...
@@ -1708,6 +1952,13 @@ const onSelectCoverChange = (value: any) => {
style=
"margin-left: 12px"
style=
"margin-left: 12px"
>
清除图片
</el-button
>
清除图片
</el-button
>
>
<el-button
type=
"primary"
size=
"small"
@
click=
"showInPaintDialog('product', '')"
style=
"margin-left: 12px"
>
局部重绘
</el-button
>
</el-form-item>
</el-form-item>
<el-form-item>
<el-form-item>
<div
style=
"width: 100%"
>
<div
style=
"width: 100%"
>
...
@@ -1899,6 +2150,7 @@ const onSelectCoverChange = (value: any) => {
...
@@ -1899,6 +2150,7 @@ const onSelectCoverChange = (value: any) => {
<video
:src=
"form.final_video"
controls
></video>
<video
:src=
"form.final_video"
controls
></video>
</el-form-item>
</el-form-item>
</el-form>
</el-form>
<!-- 授权密码框 -->
<!-- 授权密码框 -->
<el-dialog
<el-dialog
v-model=
"pwdCheckDialogVisible"
v-model=
"pwdCheckDialogVisible"
...
@@ -2015,6 +2267,53 @@ const onSelectCoverChange = (value: any) => {
...
@@ -2015,6 +2267,53 @@ const onSelectCoverChange = (value: any) => {
</div>
</div>
</
template
>
</
template
>
</el-dialog>
</el-dialog>
<!-- 局部重绘 -->
<el-dialog
v-model=
"inPaintVisible"
title=
"局部重绘"
:fullscreen=
"true"
:close-on-click-modal=
"false"
:close-on-press-escape=
"true"
:show-close=
"true"
:lock-scroll=
"true"
>
<div>
请在图片上涂抹需要保留的部分
</div>
<div
ref=
"inpaint"
:style=
"
'position: relative; width: ' +
form.img_size.width +
'px; height: ' +
form.img_size.height +
'px'
"
>
<canvas
id=
"baseCanvas"
:width=
"form.img_size.width"
:height=
"form.img_size.height"
style=
"position: absolute; left: 0; top: 0"
></canvas>
<canvas
id=
"maskCanvas"
:width=
"form.img_size.width"
:height=
"form.img_size.height"
style=
"position: absolute; left: 0; top: 0; z-index: 1; background: none"
></canvas>
</div>
<button
id=
"clearButton"
>
清除涂抹
</button>
<div>
<span>
画面描述:
</span>
<el-input
v-model=
"inPaintPrompt"
:autosize=
"true"
type=
"textarea"
></el-input>
</div>
<
template
#
footer
>
<div
class=
"dialog-footer"
>
<el-button
@
click=
"inPaintVisible = false"
>
取消
</el-button>
<el-button
type=
"primary"
@
click=
"onSubmitInPaint"
>
提交
</el-button>
</div>
</
template
>
</el-dialog>
</main>
</main>
</template>
</template>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment