From 0fd620d16ebe0d9160c5386084493ebce29f2165 Mon Sep 17 00:00:00 2001 From: usbharu <64310155+usbharu@users.noreply.github.com> Date: Wed, 4 Oct 2023 23:07:55 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=A1=E3=83=87=E3=82=A3=E3=82=A2?= =?UTF-8?q?=E3=81=AE=E5=A4=89=E6=8F=9B=E5=87=A6=E7=90=86=E3=82=92=E5=AE=9F?= =?UTF-8?q?=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 1 + .../usbharu/hideout/domain/model/MediaSave.kt | 6 ++-- .../service/media/MediaBlurhashServiceImpl.kt | 10 +++++++ .../service/media/ThumbnailGenerateService.kt | 5 +++- .../media/ThumbnailGenerateServiceImpl.kt | 28 +++++++++++++++++++ .../service/media/converter/MediaConverter.kt | 3 +- .../media/converter/MediaConverterRoot.kt | 3 +- .../media/converter/MediaConverterRootImpl.kt | 20 +++++++++++++ .../media/converter/MediaProcessService.kt | 7 ++++- .../converter/MediaProcessServiceImpl.kt | 11 +++++--- 10 files changed, 83 insertions(+), 11 deletions(-) create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/MediaBlurhashServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateServiceImpl.kt create mode 100644 src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRootImpl.kt diff --git a/build.gradle.kts b/build.gradle.kts index 4b91b4f7..0b2a4472 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -118,6 +118,7 @@ dependencies { implementation("org.springframework.security:spring-security-oauth2-jose") implementation("org.springframework.boot:spring-boot-starter-data-mongodb") implementation("org.jetbrains.exposed:exposed-spring-boot-starter:0.44.0") + implementation("io.trbl:blurhash:1.0.0") implementation("io.ktor:ktor-client-logging-jvm:$ktor_version") diff --git a/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt b/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt index cf415fff..49dc04e1 100644 --- a/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt +++ b/src/main/kotlin/dev/usbharu/hideout/domain/model/MediaSave.kt @@ -1,10 +1,10 @@ package dev.usbharu.hideout.domain.model -import java.io.InputStream +import java.io.OutputStream data class MediaSave( val name: String, val prefix: String, - val fileInputStream: InputStream, - val thumbnailInputStream: InputStream? + val fileInputStream: OutputStream, + val thumbnailInputStream: OutputStream? ) diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/MediaBlurhashServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaBlurhashServiceImpl.kt new file mode 100644 index 00000000..d2156796 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/MediaBlurhashServiceImpl.kt @@ -0,0 +1,10 @@ +package dev.usbharu.hideout.service.media + +import io.trbl.blurhash.BlurHash +import org.springframework.stereotype.Service +import java.awt.image.BufferedImage + +@Service +class MediaBlurhashServiceImpl : MediaBlurhashService { + override fun generateBlurhash(bufferedImage: BufferedImage): String = BlurHash.encode(bufferedImage) +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt index 15db6ee7..0d53fe3c 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateService.kt @@ -1,7 +1,10 @@ package dev.usbharu.hideout.service.media +import java.io.ByteArrayOutputStream import java.io.InputStream +import java.io.OutputStream interface ThumbnailGenerateService { - fun generate(bufferedImage: InputStream, width: Int, height: Int): InputStream + fun generate(bufferedImage: InputStream, width: Int, height: Int): ByteArrayOutputStream + fun generate(outputStream: OutputStream, width: Int, height: Int): ByteArrayOutputStream } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateServiceImpl.kt new file mode 100644 index 00000000..5e6d416f --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/ThumbnailGenerateServiceImpl.kt @@ -0,0 +1,28 @@ +package dev.usbharu.hideout.service.media + +import org.springframework.stereotype.Service +import java.awt.image.BufferedImage +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.io.OutputStream +import javax.imageio.ImageIO +import javax.imageio.stream.MemoryCacheImageOutputStream + +@Service +class ThumbnailGenerateServiceImpl : ThumbnailGenerateService { + override fun generate(bufferedImage: InputStream, width: Int, height: Int): ByteArrayOutputStream { + val image = ImageIO.read(bufferedImage) + return internalGenerate(image) + } + + override fun generate(outputStream: OutputStream, width: Int, height: Int): ByteArrayOutputStream { + val image = ImageIO.read(MemoryCacheImageOutputStream(outputStream)) + return internalGenerate(image) + } + + private fun internalGenerate(image: BufferedImage): ByteArrayOutputStream { + val byteArrayOutputStream = ByteArrayOutputStream() + ImageIO.write(image, "webp", byteArrayOutputStream) + return byteArrayOutputStream + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt index 6771c73d..b57c7a50 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverter.kt @@ -2,8 +2,9 @@ package dev.usbharu.hideout.service.media.converter import dev.usbharu.hideout.domain.model.hideout.dto.FileType import java.io.InputStream +import java.io.OutputStream interface MediaConverter { fun isSupport(fileType: FileType): Boolean - fun convert(inputStream: InputStream): InputStream + fun convert(inputStream: InputStream): OutputStream } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt index a032a3f1..77c99a8d 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRoot.kt @@ -2,7 +2,8 @@ package dev.usbharu.hideout.service.media.converter import dev.usbharu.hideout.domain.model.hideout.dto.FileType import java.io.InputStream +import java.io.OutputStream interface MediaConverterRoot { - suspend fun convert(fileType: FileType, inputStream: InputStream): InputStream + suspend fun convert(fileType: FileType, inputStream: InputStream): OutputStream } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRootImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRootImpl.kt new file mode 100644 index 00000000..9c005458 --- /dev/null +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaConverterRootImpl.kt @@ -0,0 +1,20 @@ +package dev.usbharu.hideout.service.media.converter + +import dev.usbharu.hideout.domain.model.hideout.dto.FileType +import org.springframework.stereotype.Service +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.io.OutputStream + +@Service +class MediaConverterRootImpl(private val converters: List) : MediaConverterRoot { + override suspend fun convert(fileType: FileType, inputStream: InputStream): OutputStream { + return converters.find { + it.isSupport(fileType) + }?.convert(inputStream) ?: inputStream.let { + val byteArrayOutputStream = ByteArrayOutputStream() + it.transferTo(byteArrayOutputStream) + byteArrayOutputStream + } + } +} diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt index 107647f5..c31ecd66 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessService.kt @@ -2,7 +2,12 @@ package dev.usbharu.hideout.service.media.converter import dev.usbharu.hideout.domain.model.hideout.dto.FileType import java.io.InputStream +import java.io.OutputStream interface MediaProcessService { - suspend fun process(fileType: FileType, file: InputStream, thumbnail: InputStream?): Pair + suspend fun process( + fileType: FileType, + file: InputStream, + thumbnail: InputStream? + ): Pair } diff --git a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt index b7fc6fd8..bbab8626 100644 --- a/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt +++ b/src/main/kotlin/dev/usbharu/hideout/service/media/converter/MediaProcessServiceImpl.kt @@ -4,8 +4,11 @@ import dev.usbharu.hideout.domain.model.hideout.dto.FileType import dev.usbharu.hideout.exception.media.MediaConvertException import dev.usbharu.hideout.service.media.ThumbnailGenerateService import org.slf4j.LoggerFactory +import org.springframework.stereotype.Service import java.io.InputStream +import java.io.OutputStream +@Service class MediaProcessServiceImpl( private val mediaConverterRoot: MediaConverterRoot, private val thumbnailGenerateService: ThumbnailGenerateService @@ -14,7 +17,7 @@ class MediaProcessServiceImpl( fileType: FileType, file: InputStream, thumbnail: InputStream? - ): Pair { + ): Pair { val fileInputStream = try { mediaConverterRoot.convert(fileType, file) @@ -28,11 +31,11 @@ class MediaProcessServiceImpl( logger.warn("Failed convert thumbnail media.", e) null } - return fileInputStream to (thumbnailInputStream ?: thumbnailGenerateService.generate( - fileInputStream, + return fileInputStream to thumbnailGenerateService.generate( + thumbnailInputStream ?: fileInputStream, 2048, 2048 - )) + ) } companion object {