Fix: separate top title and bottom content in merge image - bottom content now dynamically positioned
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,4 +1,4 @@
|
||||
#Fri Mar 06 22:42:09 CST 2026
|
||||
#Fri Mar 06 22:54:40 CST 2026
|
||||
path.4=14/classes.dex
|
||||
path.3=12/classes.dex
|
||||
path.2=10/classes.dex
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
פ8מ)ת*ר'‗&ט%<EFBFBD>!ר
|
||||
פ8מ)ת*ר'‗&ט%<EFBFBD>!רש#
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
37
|
||||
39
|
||||
0
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
ëXè¾ú¹Ñ~Ì>Ňôï`ý¿ÄJùÉïNÔ›î×úbå4å²×?Í#à“À2
|
||||
ëXè¾ú¹Ñ~Ì>Ňôï`ý¿ÄJùÉïNÔ›î×úbå4å²×?Í#à“À2èjÓ*ú3
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -401,7 +401,9 @@ fun MergeScreen(
|
||||
content,
|
||||
titleStyle,
|
||||
contentStyle,
|
||||
recorderName
|
||||
recorderName,
|
||||
title,
|
||||
content
|
||||
)
|
||||
}
|
||||
showPreview = true
|
||||
@@ -469,7 +471,9 @@ fun MergeScreen(
|
||||
content,
|
||||
titleStyle,
|
||||
contentStyle,
|
||||
recorderName
|
||||
recorderName,
|
||||
title,
|
||||
content
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -190,9 +190,11 @@ object ImageProcessor {
|
||||
content: String = "",
|
||||
titleStyle: WatermarkStyle = WatermarkStyle.Default,
|
||||
contentStyle: WatermarkStyle = WatermarkStyle.Default,
|
||||
recorderName: String = ""
|
||||
recorderName: String = "",
|
||||
bottomTitle: String = "",
|
||||
bottomContent: String = ""
|
||||
): Bitmap {
|
||||
if (images.isEmpty() && title.isBlank() && content.isBlank() && recorderName.isBlank()) {
|
||||
if (images.isEmpty() && title.isBlank() && content.isBlank() && recorderName.isBlank() && bottomTitle.isBlank() && bottomContent.isBlank()) {
|
||||
return Bitmap.createBitmap(1920, 1080, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
|
||||
@@ -205,29 +207,29 @@ object ImageProcessor {
|
||||
val cellHeight = cellWidth // 保持正方形格子
|
||||
|
||||
// 底部文字区域高度 - 动态计算
|
||||
val textAreaHeight = if (title.isNotBlank() || content.isNotBlank()) {
|
||||
val textAreaHeight = if (bottomTitle.isNotBlank() || bottomContent.isNotBlank()) {
|
||||
val padding = 30f
|
||||
val titleHeight = if (title.isNotBlank()) {
|
||||
val bTitleHeight = if (bottomTitle.isNotBlank()) {
|
||||
val titlePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
textSize = outputWidth / 25f
|
||||
}
|
||||
titlePaint.fontMetrics.let { it.descent - it.ascent }
|
||||
} else 0f
|
||||
|
||||
val contentHeight = if (content.isNotBlank()) {
|
||||
val bContentHeight = if (bottomContent.isNotBlank()) {
|
||||
val contentPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
textSize = outputWidth / 35f
|
||||
}
|
||||
val contentMaxWidth = outputWidth - padding * 2
|
||||
val contentLines = wrapText(content, contentPaint, contentMaxWidth).take(5)
|
||||
val contentLines = wrapText(bottomContent, contentPaint, contentMaxWidth).take(5)
|
||||
val lineHeight = contentPaint.fontMetrics.let { it.descent - it.ascent }
|
||||
val titleSpacing = if (title.isNotBlank()) titleHeight + lineHeight + 20 else lineHeight
|
||||
val titleSpacing = if (bottomTitle.isNotBlank()) bTitleHeight + lineHeight + 20 else lineHeight
|
||||
titleSpacing + contentLines.size * lineHeight + padding
|
||||
} else {
|
||||
padding + titleHeight + padding
|
||||
padding + bTitleHeight + padding
|
||||
}
|
||||
|
||||
maxOf(150f, contentHeight)
|
||||
maxOf(150f, bContentHeight)
|
||||
} else {
|
||||
0f
|
||||
}
|
||||
@@ -319,39 +321,39 @@ object ImageProcessor {
|
||||
)
|
||||
|
||||
val padding = 30f
|
||||
val titleHeight: Float
|
||||
val bTitleHeight: Float
|
||||
|
||||
// 绘制标题 - 粗体白色居中
|
||||
if (title.isNotBlank()) {
|
||||
if (bottomTitle.isNotBlank()) {
|
||||
val titlePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
textSize = outputWidth / 25f
|
||||
color = android.graphics.Color.WHITE
|
||||
typeface = Typeface.create("sans-serif", Typeface.BOLD) // 粗体无衬线
|
||||
typeface = Typeface.create("sans-serif", Typeface.BOLD)
|
||||
textAlign = android.graphics.Paint.Align.CENTER
|
||||
}
|
||||
|
||||
titleHeight = titlePaint.fontMetrics.let { it.descent - it.ascent }
|
||||
canvas.drawText(title, outputWidth / 2f, textTop + padding + titleHeight, titlePaint)
|
||||
bTitleHeight = titlePaint.fontMetrics.let { it.descent - it.ascent }
|
||||
canvas.drawText(bottomTitle, outputWidth / 2f, textTop + padding + bTitleHeight, titlePaint)
|
||||
} else {
|
||||
titleHeight = 0f
|
||||
bTitleHeight = 0f
|
||||
}
|
||||
|
||||
// 绘制内容 - 细体白色靠左
|
||||
if (content.isNotBlank()) {
|
||||
if (bottomContent.isNotBlank()) {
|
||||
val contentPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
textSize = outputWidth / 35f
|
||||
color = android.graphics.Color.WHITE
|
||||
typeface = Typeface.create("sans-serif", Typeface.NORMAL) // 细体
|
||||
typeface = Typeface.create("sans-serif", Typeface.NORMAL)
|
||||
textAlign = android.graphics.Paint.Align.LEFT
|
||||
}
|
||||
|
||||
val contentMaxWidth = outputWidth - padding * 2
|
||||
val contentLines = wrapText(content, contentPaint, contentMaxWidth)
|
||||
val contentLines = wrapText(bottomContent, contentPaint, contentMaxWidth)
|
||||
val lineHeight = contentPaint.fontMetrics.let { it.descent - it.ascent }
|
||||
|
||||
// 内容起始Y坐标 - 标题下方再往下移一行
|
||||
val contentStartY = if (title.isNotBlank()) {
|
||||
textTop + padding + titleHeight + lineHeight + 20
|
||||
val contentStartY = if (bottomTitle.isNotBlank()) {
|
||||
textTop + padding + bTitleHeight + lineHeight + 20
|
||||
} else {
|
||||
textTop + padding + lineHeight * 2
|
||||
}
|
||||
@@ -363,6 +365,7 @@ object ImageProcessor {
|
||||
y += lineHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 绘制记录人信息 - 右下角,小字
|
||||
if (recorderName.isNotBlank()) {
|
||||
@@ -379,9 +382,6 @@ object ImageProcessor {
|
||||
return result
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩放并居中裁剪Bitmap
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user