feat: support generate ascii art with reply
This commit is contained in:
2 files changed
+87
-51
No files matched your search
@@ -76,19 +76,26 @@ class FancyBot : OneBotListener {
|
||||
calculateResult?.let { message.reply(calculateResult) }
|
||||
}
|
||||
|
||||
if (message.message.any { it.type == ArrayMessageType.reply }) { // Image url parse
|
||||
if (message.message.any { it.type == ArrayMessageType.reply }) {
|
||||
val command = message.message.reversed().find { it.type == ArrayMessageType.text }!!.data.text!!
|
||||
val replyId = message.message.find { it.type == ArrayMessageType.reply }!!.data.id!!
|
||||
val getMsg = this.getMessage(replyId.toString().toLong())
|
||||
if (command.contains("/ascii") || command.contains("/asc")) {
|
||||
// 使用回复消息的方式直接对一个图片进行生成Ascii art的操作
|
||||
val url = AsciiArtCommand.getImageUrl(getMsg)
|
||||
val image = AsciiArtCommand.generateAsciiArt(url)
|
||||
message.reply(image)
|
||||
}
|
||||
if (command.contains("图来") || command.contains("图链")) {
|
||||
val getMsg = this.getMessage(replyId.toString().toLong())
|
||||
// 获取一个或多个图片的链接, 并且生成一个或多个短链接
|
||||
ImageURLCommand.callback(message, getMsg)
|
||||
}
|
||||
if (command.contains("reaction")) {
|
||||
val getMsg = this.getMessage(replyId.toString().toLong())
|
||||
// 使用reaction刷屏回应一条消息
|
||||
ReactionCommand.reaction(this, message, getMsg.messageId)
|
||||
}
|
||||
if (command.contains("图床")) {
|
||||
val getMsg = this.getMessage(replyId.toString().toLong())
|
||||
// 将一个图片上传到图床
|
||||
val imagesUrl = ImageURLCommand.getImageUrl(getMsg)
|
||||
if (imagesUrl.isEmpty()) {
|
||||
message.reply("这个消息里没有图片呢!")
|
||||
|
||||
@@ -15,11 +15,13 @@ import cn.rtast.fancybot.util.misc.ImageBed
|
||||
import cn.rtast.fancybot.util.misc.makeGif
|
||||
import cn.rtast.fancybot.util.str.encodeToBase64
|
||||
import cn.rtast.fancybot.util.misc.toByteArray
|
||||
import cn.rtast.rob.entity.GetMessage
|
||||
import cn.rtast.rob.entity.GroupMessage
|
||||
import cn.rtast.rob.enums.ArrayMessageType
|
||||
import cn.rtast.rob.util.BaseCommand
|
||||
import cn.rtast.rob.util.ob.MessageChain
|
||||
import cn.rtast.rob.util.ob.OneBotListener
|
||||
import cn.rtast.rob.util.ob.asMessageChain
|
||||
import com.madgag.gif.fmsware.GifDecoder
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
@@ -91,62 +93,89 @@ class AsciiArtCommand : BaseCommand() {
|
||||
return img
|
||||
}
|
||||
|
||||
suspend fun generateAsciiArt(url: String): MessageChain {
|
||||
val gifStream = withContext(Dispatchers.IO) { URI(url).toURL().openStream() }
|
||||
val decoder = GifDecoder()
|
||||
try {
|
||||
decoder.read(gifStream)
|
||||
if (decoder.frameCount == 0) {
|
||||
val bufferedImage = withContext(Dispatchers.IO) { ImageIO.read(URI(url).toURL()) }
|
||||
val imageBytes = bufferedImage.convertToAscii()
|
||||
.saveAsciiArtToImage(bufferedImage.width, bufferedImage.height)
|
||||
.toByteArray()
|
||||
val imageBedUrl = ImageBed.upload(imageBytes, imageBytes.getFileType())
|
||||
val msg = MessageChain.Builder()
|
||||
.addImage(imageBytes.encodeToBase64(), true)
|
||||
.addText(imageBedUrl)
|
||||
.build()
|
||||
return msg
|
||||
} else {
|
||||
logger.info("制作GIF Ascii art中, 总帧数: ${decoder.frameCount}")
|
||||
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) }
|
||||
val asciiFrames = mutableListOf<BufferedImage>()
|
||||
val width = frames.first().width
|
||||
val height = frames.first().height
|
||||
frames.forEachIndexed { index, item ->
|
||||
asciiFrames.add(item.convertToAscii().saveAsciiArtToImage(width, height))
|
||||
logger.info("帧:${index}处理完成")
|
||||
}
|
||||
logger.info("合成GIF中...")
|
||||
val gifBytes = decoder.makeGif(asciiFrames)
|
||||
val imageBedUrl = ImageBed.upload(gifBytes, gifBytes.getFileType()).makeShortLink()
|
||||
logger.info("合并完成")
|
||||
val gifBase64 = gifBytes.encodeToBase64()
|
||||
logger.info("处理后的图片大小: ${(gifBytes.size / 1024 / 1024).toInt()}MB")
|
||||
val msg = MessageChain.Builder()
|
||||
.addImage(gifBase64, true)
|
||||
.addText(imageBedUrl)
|
||||
.build()
|
||||
return msg
|
||||
}
|
||||
} catch (_: OutOfMemoryError) {
|
||||
return listOf("GIF处理失败: 内存溢出").asMessageChain()
|
||||
logger.info("GIF处理失败: 内存溢出")
|
||||
} catch (e: Exception) {
|
||||
return listOf("处理GIF失败: ${e.message}").asMessageChain()
|
||||
logger.info("gif处理失败: ${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun callback(message: GroupMessage) {
|
||||
if (message.sender.userId !in waitingList) return
|
||||
waitingList.removeIf { it == message.sender.userId }
|
||||
if (message.message.any { it.type == ArrayMessageType.image }
|
||||
|| message.message.any { it.type == ArrayMessageType.mface }) {
|
||||
val url = if (message.message.any { it.type == ArrayMessageType.image })
|
||||
message.message.find { it.type == ArrayMessageType.image }!!.data.file!!
|
||||
else message.message.find { it.type == ArrayMessageType.mface }!!.data.url!!
|
||||
val gifStream = withContext(Dispatchers.IO) { URI(url).toURL().openStream() }
|
||||
val decoder = GifDecoder()
|
||||
try {
|
||||
decoder.read(gifStream)
|
||||
if (decoder.frameCount == 0) {
|
||||
val bufferedImage = withContext(Dispatchers.IO) { ImageIO.read(URI(url).toURL()) }
|
||||
val imageBytes = bufferedImage.convertToAscii()
|
||||
.saveAsciiArtToImage(bufferedImage.width, bufferedImage.height)
|
||||
.toByteArray()
|
||||
val imageBedUrl = ImageBed.upload(imageBytes, imageBytes.getFileType())
|
||||
val msg = MessageChain.Builder()
|
||||
.addImage(imageBytes.encodeToBase64(), true)
|
||||
.addText(imageBedUrl)
|
||||
.build()
|
||||
message.reply(msg)
|
||||
} else {
|
||||
logger.info("制作GIF Ascii art中, 总帧数: ${decoder.frameCount}")
|
||||
val frames = (0 until decoder.frameCount).map { decoder.getFrame(it) }
|
||||
val asciiFrames = mutableListOf<BufferedImage>()
|
||||
val width = frames.first().width
|
||||
val height = frames.first().height
|
||||
frames.forEachIndexed { index, item ->
|
||||
asciiFrames.add(item.convertToAscii().saveAsciiArtToImage(width, height))
|
||||
logger.info("帧:${index}处理完成")
|
||||
}
|
||||
logger.info("合成GIF中...")
|
||||
val gifBytes = decoder.makeGif(asciiFrames)
|
||||
val imageBedUrl = ImageBed.upload(gifBytes, gifBytes.getFileType()).makeShortLink()
|
||||
logger.info("合并完成")
|
||||
val gifBase64 = gifBytes.encodeToBase64()
|
||||
logger.info("处理后的图片大小: ${(gifBytes.size / 1024 / 1024).toInt()}MB")
|
||||
val msg = MessageChain.Builder()
|
||||
.addImage(gifBase64, true)
|
||||
.addText(imageBedUrl)
|
||||
.build()
|
||||
message.reply(msg)
|
||||
}
|
||||
} catch (_: OutOfMemoryError) {
|
||||
message.reply("GIF处理失败: 内存溢出")
|
||||
logger.info("GIF处理失败: 内存溢出")
|
||||
} catch (e: Exception) {
|
||||
message.reply("处理GIF失败: ${e.message}")
|
||||
logger.info("gif处理失败: ${e.message}")
|
||||
}
|
||||
val url = this.getImageUrl(message)
|
||||
val msg = this.generateAsciiArt(url)
|
||||
message.reply(msg)
|
||||
} else {
|
||||
message.reply("回复错误已取消本次操作")
|
||||
}
|
||||
}
|
||||
|
||||
fun getImageUrl(groupMessage: GroupMessage): String {
|
||||
return getImageUrlFromUnified(toUnifiedMessage(groupMessage))
|
||||
}
|
||||
|
||||
fun getImageUrl(getMessageData: GetMessage.Data): String {
|
||||
return getImageUrlFromUnified(toUnifiedMessage(getMessageData))
|
||||
}
|
||||
|
||||
private fun getImageUrlFromUnified(messages: List<UnifiedMessage>): String {
|
||||
return if (messages.any { it.type == ArrayMessageType.image })
|
||||
messages.find { it.type == ArrayMessageType.image }!!.file!!
|
||||
else messages.find { it.type == ArrayMessageType.mface }!!.url!!
|
||||
}
|
||||
|
||||
private fun toUnifiedMessage(groupMessage: GroupMessage): List<UnifiedMessage> {
|
||||
return groupMessage.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) }
|
||||
}
|
||||
|
||||
private fun toUnifiedMessage(getMessageData: GetMessage.Data): List<UnifiedMessage> {
|
||||
return getMessageData.message.map { UnifiedMessage(it.type, it.data.file, it.data.url) }
|
||||
}
|
||||
|
||||
private data class UnifiedMessage(val type: ArrayMessageType, val file: String?, val url: String?)
|
||||
}
|
||||
|
||||
override suspend fun executeGroup(listener: OneBotListener, message: GroupMessage, args: List<String>) {
|
||||
|
||||
Reference in New Issue
Block a user