diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt index e52fadf50..2578786fe 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookAnalyzer.kt @@ -136,13 +136,8 @@ class BookAnalyzer( } val thumbnail = try { - when (book.media.profile) { - MediaProfile.DIVINA -> divinaExtractors[book.media.mediaType]?.getEntryStream(book.book.path, book.media.pages.first().fileName) - MediaProfile.PDF -> pdfExtractor.getPageContentAsImage(book.book.path, 1).content - MediaProfile.EPUB -> epubExtractor.getCover(book.book.path)?.content - null -> null - }?.let { cover -> - imageConverter.resizeImageToByteArray(cover, thumbnailType, komgaSettingsProvider.thumbnailSize.maxEdge) + getPoster(book)?.let { cover -> + imageConverter.resizeImageToByteArray(cover.content, thumbnailType, komgaSettingsProvider.thumbnailSize.maxEdge) } } catch (ex: Exception) { logger.warn(ex) { "Could not generate thumbnail for book: $book" } @@ -159,6 +154,19 @@ class BookAnalyzer( ) } + fun getPoster(book: BookWithMedia): BookPageContent? = when (book.media.profile) { + MediaProfile.DIVINA -> divinaExtractors[book.media.mediaType]?.getEntryStream(book.book.path, book.media.pages.first().fileName)?.let { + BookPageContent( + it, + book.media.pages.first().mediaType, + ) + } + + MediaProfile.PDF -> pdfExtractor.getPageContentAsImage(book.book.path, 1) + MediaProfile.EPUB -> epubExtractor.getCover(book.book.path) + null -> null + } + @Throws( MediaNotReadyException::class, IndexOutOfBoundsException::class, diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookLifecycle.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookLifecycle.kt index 87b8033d7..d8518f507 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/BookLifecycle.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/BookLifecycle.kt @@ -181,7 +181,7 @@ class BookLifecycle( return selected } - fun getThumbnailBytes(bookId: String, resizeTo: Int? = null): ByteArray? { + fun getThumbnailBytes(bookId: String, resizeTo: Int? = null): BookPageContent? { getThumbnail(bookId)?.let { val thumbnailBytes = when { it.thumbnail != null -> it.thumbnail @@ -190,19 +190,32 @@ class BookLifecycle( } if (resizeTo != null) { - return try { - imageConverter.resizeImageToByteArray(thumbnailBytes, resizeTargetFormat, resizeTo) + try { + return BookPageContent( + imageConverter.resizeImageToByteArray(thumbnailBytes, resizeTargetFormat, resizeTo), + resizeTargetFormat.mediaType, + ) } catch (e: Exception) { logger.error(e) { "Resize thumbnail of book $bookId to $resizeTo: failed" } - thumbnailBytes } } - return thumbnailBytes + return BookPageContent(thumbnailBytes, it.mediaType) } return null } + fun getThumbnailBytesOriginal(bookId: String): BookPageContent? { + val thumbnail = getThumbnail(bookId) ?: return null + return if (thumbnail.type == ThumbnailBook.Type.GENERATED) { + val book = bookRepository.findByIdOrNull(bookId) ?: return null + val media = mediaRepository.findById(book.id) + bookAnalyzer.getPoster(BookWithMedia(book, media)) + } else { + getThumbnailBytes(bookId) + } + } + fun getThumbnailBytesByThumbnailId(thumbnailId: String): ByteArray? = thumbnailBookRepository.findByIdOrNull(thumbnailId)?.let { getBytesFromThumbnailBook(it) diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/ReadListLifecycle.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/ReadListLifecycle.kt index 401647db1..d52f21237 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/ReadListLifecycle.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/ReadListLifecycle.kt @@ -117,7 +117,7 @@ class ReadListLifecycle( this.take(4) } - val images = ids.mapNotNull { bookLifecycle.getThumbnailBytes(it) } + val images = ids.mapNotNull { bookLifecycle.getThumbnailBytes(it)?.content } return mosaicGenerator.createMosaic(images) } diff --git a/komga/src/main/kotlin/org/gotson/komga/domain/service/SeriesLifecycle.kt b/komga/src/main/kotlin/org/gotson/komga/domain/service/SeriesLifecycle.kt index 79696cb32..dd8b99eae 100644 --- a/komga/src/main/kotlin/org/gotson/komga/domain/service/SeriesLifecycle.kt +++ b/komga/src/main/kotlin/org/gotson/komga/domain/service/SeriesLifecycle.kt @@ -257,7 +257,7 @@ class SeriesLifecycle( ?: bookRepository.findLastIdInSeriesOrNull(seriesId) Library.SeriesCover.LAST -> bookRepository.findLastIdInSeriesOrNull(seriesId) } - if (bookId != null) return bookLifecycle.getThumbnailBytes(bookId) + if (bookId != null) return bookLifecycle.getThumbnailBytes(bookId)?.content } return null diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/OpdsCommonController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/OpdsCommonController.kt index 64c81fef6..283c8f097 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/OpdsCommonController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/OpdsCommonController.kt @@ -3,10 +3,10 @@ package org.gotson.komga.interfaces.api.opds import io.swagger.v3.oas.annotations.media.Content import io.swagger.v3.oas.annotations.media.Schema import io.swagger.v3.oas.annotations.responses.ApiResponse -import org.gotson.komga.domain.model.ThumbnailBook import org.gotson.komga.domain.persistence.BookRepository import org.gotson.komga.domain.persistence.SeriesMetadataRepository import org.gotson.komga.domain.service.BookLifecycle +import org.gotson.komga.infrastructure.image.ImageConverter import org.gotson.komga.infrastructure.image.ImageType import org.gotson.komga.infrastructure.security.KomgaPrincipal import org.gotson.komga.interfaces.api.checkContentRestriction @@ -23,6 +23,7 @@ class OpdsCommonController( private val seriesMetadataRepository: SeriesMetadataRepository, private val bookRepository: BookRepository, private val bookLifecycle: BookLifecycle, + private val imageConverter: ImageConverter, ) { @ApiResponse(content = [Content(schema = Schema(type = "string", format = "binary"))]) @@ -38,11 +39,8 @@ class OpdsCommonController( @PathVariable bookId: String, ): ByteArray { principal.user.checkContentRestriction(bookId, bookRepository, seriesMetadataRepository) - val thumbnail = bookLifecycle.getThumbnail(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) - return if (thumbnail.type == ThumbnailBook.Type.GENERATED) { - bookLifecycle.getBookPage(bookRepository.findByIdOrNull(bookId)!!, 1, ImageType.JPEG).content - } else { - bookLifecycle.getThumbnailBytes(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) - } + val poster = bookLifecycle.getThumbnailBytesOriginal(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) + return if (poster.mediaType != ImageType.JPEG.mediaType) imageConverter.convertImage(poster.content, ImageType.JPEG.imageIOFormat) + else poster.content } } diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/OpdsController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/OpdsController.kt index a5be80272..e9ee961f2 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/OpdsController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/opds/v1/OpdsController.kt @@ -670,7 +670,7 @@ class OpdsController( principal.user.checkContentRestriction(bookId, bookRepository, seriesMetadataRepository) val thumbnail = bookLifecycle.getThumbnail(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) - return bookLifecycle.getThumbnailBytes(bookId, if (thumbnail.type == ThumbnailBook.Type.GENERATED) null else komgaSettingsProvider.thumbnailSize.maxEdge) + return bookLifecycle.getThumbnailBytes(bookId, if (thumbnail.type == ThumbnailBook.Type.GENERATED) null else komgaSettingsProvider.thumbnailSize.maxEdge)?.content ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) } diff --git a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/BookController.kt b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/BookController.kt index 5f6108813..8e6169f49 100644 --- a/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/BookController.kt +++ b/komga/src/main/kotlin/org/gotson/komga/interfaces/api/rest/BookController.kt @@ -298,7 +298,7 @@ class BookController( ): ByteArray { principal.user.checkContentRestriction(bookId, bookRepository, seriesMetadataRepository) - return bookLifecycle.getThumbnailBytes(bookId) ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) + return bookLifecycle.getThumbnailBytes(bookId)?.content ?: throw ResponseStatusException(HttpStatus.NOT_FOUND) } @ApiResponse(content = [Content(schema = Schema(type = "string", format = "binary"))])