添加拼图底部标题和内容区域
This commit is contained in:
@@ -365,20 +365,12 @@ fun MergeScreen(
|
||||
context,
|
||||
imageItems,
|
||||
layoutType,
|
||||
imageQuality
|
||||
).let { bitmap ->
|
||||
if (title.isNotBlank() || content.isNotBlank()) {
|
||||
ImageProcessor.addTextToBitmap(
|
||||
bitmap,
|
||||
title,
|
||||
content,
|
||||
titleStyle,
|
||||
contentStyle
|
||||
)
|
||||
} else {
|
||||
bitmap
|
||||
}
|
||||
}
|
||||
imageQuality,
|
||||
title,
|
||||
content,
|
||||
titleStyle,
|
||||
contentStyle
|
||||
)
|
||||
}
|
||||
showPreview = true
|
||||
}
|
||||
@@ -439,20 +431,12 @@ fun MergeScreen(
|
||||
context,
|
||||
imageItems,
|
||||
layoutType,
|
||||
imageQuality
|
||||
).let { mergedBitmap ->
|
||||
if (title.isNotBlank() || content.isNotBlank()) {
|
||||
ImageProcessor.addTextToBitmap(
|
||||
mergedBitmap,
|
||||
title,
|
||||
content,
|
||||
titleStyle,
|
||||
contentStyle
|
||||
)
|
||||
} else {
|
||||
mergedBitmap
|
||||
}
|
||||
}
|
||||
imageQuality,
|
||||
title,
|
||||
content,
|
||||
titleStyle,
|
||||
contentStyle
|
||||
)
|
||||
}
|
||||
|
||||
val fileName = ImageProcessor.generateFileName(title.ifBlank { "合成" })
|
||||
|
||||
@@ -155,9 +155,13 @@ object ImageProcessor {
|
||||
context: Context,
|
||||
images: List<ImageItem>,
|
||||
layoutType: MergeLayoutType,
|
||||
quality: ImageQuality
|
||||
quality: ImageQuality,
|
||||
title: String = "",
|
||||
content: String = "",
|
||||
titleStyle: WatermarkStyle = WatermarkStyle.Default,
|
||||
contentStyle: WatermarkStyle = WatermarkStyle.Default
|
||||
): Bitmap {
|
||||
if (images.isEmpty()) {
|
||||
if (images.isEmpty() && title.isBlank() && content.isBlank()) {
|
||||
return Bitmap.createBitmap(1920, 1080, Bitmap.Config.ARGB_8888)
|
||||
}
|
||||
|
||||
@@ -165,9 +169,20 @@ object ImageProcessor {
|
||||
val rows = layoutType.rows
|
||||
|
||||
val outputWidth = 1920
|
||||
val outputHeight = 1080
|
||||
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 canvas = Canvas(result)
|
||||
@@ -175,6 +190,7 @@ object ImageProcessor {
|
||||
|
||||
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||
|
||||
// 绘制图片网格
|
||||
images.forEachIndexed { index, imageItem ->
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user