feat: メディアの変換処理を実装

This commit is contained in:
usbharu 2023-10-04 23:07:55 +09:00
parent bbf3249c45
commit 0fd620d16e
10 changed files with 83 additions and 11 deletions

View File

@ -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")

View File

@ -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?
)

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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<MediaConverter>) : 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
}
}
}

View File

@ -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<InputStream, InputStream>
suspend fun process(
fileType: FileType,
file: InputStream,
thumbnail: InputStream?
): Pair<OutputStream, OutputStream>
}

View File

@ -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<InputStream, InputStream> {
): Pair<OutputStream, OutputStream> {
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 {