feat(facemask): 黑丝网眼加粗并给 Seedance 提示词追加忽略网格说明

This commit is contained in:
2026-08-07 14:30:43 +08:00
parent d275a97946
commit 554dea6252
2 changed files with 19 additions and 5 deletions
+12 -4
View File
@@ -278,13 +278,17 @@ func applyFaceNotice(b []byte) ([]byte, error) {
// drawStocking 在给定区域上盖一层黑丝网眼:细密的深色网格线,遮住五官细节但保留轮廓。
func drawStocking(dst *image.RGBA, r image.Rectangle) {
r = r.Intersect(dst.Bounds())
step := r.Dx() / 18
if step < 4 {
step = 4
step := r.Dx() / 24
if step < 3 {
step = 3
}
line := step / 2
if line < 1 {
line = 1
}
for y := r.Min.Y; y < r.Max.Y; y++ {
for x := r.Min.X; x < r.Max.X; x++ {
if (x-r.Min.X)%step != 0 && (y-r.Min.Y)%step != 0 {
if (x-r.Min.X)%step >= line && (y-r.Min.Y)%step >= line {
continue
}
c := dst.RGBAAt(x, y)
@@ -295,3 +299,7 @@ func drawStocking(dst *image.RGBA, r image.Rectangle) {
}
}
}
// faceMaskPromptNote 附加到 Seedance 提示词后:告知模型参考图脸部的网格线只是打码,
// 需要忽略网格本身并完整还原面部细节。
const faceMaskPromptNote = "参考图人物脸部覆盖的细密网格线仅为隐私打码,不是人物本身的特征:生成时请完全忽略这些网格线,不要在画面中出现任何网格、方格、纹理或遮挡;请依据参考图的五官轮廓完整还原人物真实面孔,保留妆容、眉眼、发型、发饰、耳饰、头冠等一切面部与头部装饰细节,人物面部必须清晰完整、前后镜头保持一致。"
+7 -1
View File
@@ -1803,7 +1803,9 @@ func (s *V1Service) generateAdobeVideo(ctx context.Context, eventID string, mode
}
// Seedance 参考图先做人脸打码再上传;检不出人脸就沿用原图,
// 检测器不可用则直接报错,避免把未打码的人脸传给上游。
prompt := in.Prompt
if isSeedanceModel(modelItem.ID) {
faceMasked := false
for i, r := range imgRefs {
marked, mErr := applyFaceNotice(r)
if errors.Is(mErr, ErrNoFaceDetected) {
@@ -1813,6 +1815,10 @@ func (s *V1Service) generateAdobeVideo(ctx context.Context, eventID string, mode
return nil, "", fmt.Errorf("face mask: %w", mErr)
}
imgRefs[i] = marked
faceMasked = true
}
if faceMasked {
prompt = strings.TrimSpace(prompt + "\n\n" + faceMaskPromptNote)
}
}
@@ -1859,7 +1865,7 @@ func (s *V1Service) generateAdobeVideo(ctx context.Context, eventID string, mode
}
audioBlobIDs = append(audioBlobIDs, id)
}
bytes, meta, genErr := s.adobe.GenerateVideo(ctx, token.Value, engine, in.Prompt, aspectRatio, durationSeconds, resolution, referenceMode, upstreamModel, blobIDs, videoBlobIDs, audioBlobIDs, downloadResult)
bytes, meta, genErr := s.adobe.GenerateVideo(ctx, token.Value, engine, prompt, aspectRatio, durationSeconds, resolution, referenceMode, upstreamModel, blobIDs, videoBlobIDs, audioBlobIDs, downloadResult)
if genErr == nil {
videoURL = strings.TrimSpace(stringValue(meta["video_url"]))
}