添加拼图底部标题和内容区域

This commit is contained in:
2026-03-02 22:58:58 +08:00
parent d2ec0c9b01
commit 11521e29bd
2 changed files with 123 additions and 32 deletions

View File

@@ -365,20 +365,12 @@ fun MergeScreen(
context, context,
imageItems, imageItems,
layoutType, layoutType,
imageQuality imageQuality,
).let { bitmap ->
if (title.isNotBlank() || content.isNotBlank()) {
ImageProcessor.addTextToBitmap(
bitmap,
title, title,
content, content,
titleStyle, titleStyle,
contentStyle contentStyle
) )
} else {
bitmap
}
}
} }
showPreview = true showPreview = true
} }
@@ -439,20 +431,12 @@ fun MergeScreen(
context, context,
imageItems, imageItems,
layoutType, layoutType,
imageQuality imageQuality,
).let { mergedBitmap ->
if (title.isNotBlank() || content.isNotBlank()) {
ImageProcessor.addTextToBitmap(
mergedBitmap,
title, title,
content, content,
titleStyle, titleStyle,
contentStyle contentStyle
) )
} else {
mergedBitmap
}
}
} }
val fileName = ImageProcessor.generateFileName(title.ifBlank { "合成" }) val fileName = ImageProcessor.generateFileName(title.ifBlank { "合成" })

View File

@@ -155,9 +155,13 @@ object ImageProcessor {
context: Context, context: Context,
images: List<ImageItem>, images: List<ImageItem>,
layoutType: MergeLayoutType, layoutType: MergeLayoutType,
quality: ImageQuality quality: ImageQuality,
title: String = "",
content: String = "",
titleStyle: WatermarkStyle = WatermarkStyle.Default,
contentStyle: WatermarkStyle = WatermarkStyle.Default
): Bitmap { ): Bitmap {
if (images.isEmpty()) { if (images.isEmpty() && title.isBlank() && content.isBlank()) {
return Bitmap.createBitmap(1920, 1080, Bitmap.Config.ARGB_8888) return Bitmap.createBitmap(1920, 1080, Bitmap.Config.ARGB_8888)
} }
@@ -165,9 +169,20 @@ object ImageProcessor {
val rows = layoutType.rows val rows = layoutType.rows
val outputWidth = 1920 val outputWidth = 1920
val outputHeight = 1080
val cellWidth = outputWidth / cols val cellWidth = outputWidth / cols
val cellHeight = outputHeight / rows val cellHeight = outputWidth / cols // 保持正方形格子
// 底部文字区域高度
val textAreaHeight = if (title.isNotBlank() || content.isNotBlank()) {
200 // 200像素高度的文字区域
} else {
0
}
// 图片区域高度
val imageAreaHeight = cellHeight * rows
val outputHeight = imageAreaHeight + textAreaHeight
val result = Bitmap.createBitmap(outputWidth, outputHeight, Bitmap.Config.ARGB_8888) val result = Bitmap.createBitmap(outputWidth, outputHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(result) val canvas = Canvas(result)
@@ -175,6 +190,7 @@ object ImageProcessor {
val paint = Paint(Paint.ANTI_ALIAS_FLAG) val paint = Paint(Paint.ANTI_ALIAS_FLAG)
// 绘制图片网格
images.forEachIndexed { index, imageItem -> images.forEachIndexed { index, imageItem ->
if (index >= rows * cols) return@forEachIndexed if (index >= rows * cols) return@forEachIndexed
@@ -208,6 +224,97 @@ object ImageProcessor {
} }
} }
// 绘制底部文字区域
if (textAreaHeight > 0) {
val textTop = imageAreaHeight
// 绘制白色背景
canvas.drawRect(
0f, textTop.toFloat(),
outputWidth.toFloat(), outputHeight.toFloat(),
Paint().apply { color = Color.WHITE }
)
// 绘制分割线
canvas.drawLine(
0f, textTop.toFloat(),
outputWidth.toFloat(), textTop.toFloat(),
Paint().apply {
color = Color.LTGRAY
strokeWidth = 2f
}
)
// 绘制标题
if (title.isNotBlank()) {
val titlePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
textSize = titleStyle.fontSize * 2f // 放大标题
color = titleStyle.textColor.toArgb()
typeface = Typeface.DEFAULT_BOLD
textAlign = Paint.Align.CENTER
}
// 标题背景
val titleBgPaint = Paint().apply {
color = titleStyle.backgroundColor.toArgb()
}
val titleWidth = titlePaint.measureText(title)
val titleHeight = titlePaint.fontMetrics.let { it.descent - it.ascent }
val titleBgRect = RectF(
(outputWidth - titleWidth) / 2 - 20,
textTop + 20f,
(outputWidth + titleWidth) / 2 + 20,
textTop + 20f + titleHeight + 20
)
canvas.drawRoundRect(titleBgRect, 8f, 8f, titleBgPaint)
// 标题文字
canvas.drawText(title, outputWidth / 2f, textTop + 20f + titleHeight, titlePaint)
}
// 绘制内容
if (content.isNotBlank()) {
val contentPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
textSize = contentStyle.fontSize * 1.5f // 放大内容
color = contentStyle.textColor.toArgb()
typeface = Typeface.DEFAULT
}
val padding = 40f
val contentMaxWidth = outputWidth - padding * 2
val contentLines = wrapText(content, contentPaint, contentMaxWidth)
val lineHeight = contentPaint.fontMetrics.let { it.descent - it.ascent }
// 内容背景
val contentBgPaint = Paint().apply {
color = contentStyle.backgroundColor.toArgb()
}
// 从标题下方开始绘制内容
val contentStartY = if (title.isNotBlank()) {
textTop + 80f + lineHeight
} else {
textTop + 20f + lineHeight
}
val totalContentHeight = contentLines.size * lineHeight + 20
val contentBgRect = RectF(
padding - 10,
contentStartY - lineHeight - 10,
outputWidth - padding + 10,
contentStartY + totalContentHeight
)
canvas.drawRoundRect(contentBgRect, 8f, 8f, contentBgPaint)
// 内容文字
var y = contentStartY
contentLines.forEach { line ->
canvas.drawText(line, padding, y, contentPaint)
y += lineHeight
}
}
}
return result return result
} }