EditPageScreen: apply output quad
This commit is contained in:
@@ -185,7 +185,7 @@ class MainActivity : ComponentActivity() {
|
||||
onLoad = { id -> viewModel.loadCropInitialState(id)},
|
||||
initState = cropInitialState,
|
||||
navigation = navigation,
|
||||
onUpdatePageQuad = { id, quad, onComplete -> },
|
||||
onUpdatePageQuad = { quad -> viewModel.setCurrentPageUserQuad(quad) },
|
||||
)
|
||||
}
|
||||
is Screen.Main.Document -> {
|
||||
|
||||
@@ -49,6 +49,7 @@ import org.fairscan.app.ui.state.DocumentUiModel
|
||||
import org.fairscan.app.ui.state.PageThumbnail
|
||||
import org.fairscan.imageprocessing.ColorMode
|
||||
import org.fairscan.imageprocessing.ImageSize
|
||||
import org.fairscan.imageprocessing.Quad
|
||||
import kotlin.math.min
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@@ -189,6 +190,22 @@ class MainViewModel(val imageRepository: ImageRepository): ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun setCurrentPageUserQuad(userQuad: Quad) {
|
||||
viewModelScope.launch {
|
||||
val currentPage = currentPage()
|
||||
val totalRotation = currentPage.totalRotation()
|
||||
val rotateIterations = (4 - totalRotation.degrees / 90) % 4
|
||||
val newQuad = userQuad.rotate90(rotateIterations, ImageSize(1, 1))
|
||||
_loadingPageId.value = currentPage.id
|
||||
val pages = withContext(Dispatchers.IO) {
|
||||
imageRepository.setUserQuad(currentPage.id, newQuad)
|
||||
imageRepository.pages()
|
||||
}
|
||||
_pages.value = pages
|
||||
_loadingPageId.value = null
|
||||
}
|
||||
}
|
||||
|
||||
private fun currentPage(): ScanPage {
|
||||
val index = _currentPageIndex.value
|
||||
val pages = _pages.value
|
||||
@@ -234,8 +251,7 @@ class MainViewModel(val imageRepository: ImageRepository): ViewModel() {
|
||||
?: return@launch
|
||||
|
||||
val metadata = page.metadata
|
||||
val baseRotation = metadata?.baseRotation ?: Rotation.R0
|
||||
val rotation = baseRotation.add(page.manualRotation)
|
||||
val rotation = page.totalRotation()
|
||||
|
||||
val bitmap = withContext(Dispatchers.IO) {
|
||||
val source = imageRepository.source(page.id)
|
||||
|
||||
@@ -40,6 +40,8 @@ data class PageV2(
|
||||
val baseRotationDegrees: Int = 0,
|
||||
val manualRotationDegrees: Int = 0,
|
||||
val quad: NormalizedQuad? = null,
|
||||
val quadVersion: Int = 0,
|
||||
val userQuad: NormalizedQuad? = null,
|
||||
val isColored: Boolean? = null,
|
||||
val colorMode: ColorMode? = null,
|
||||
)
|
||||
|
||||
@@ -27,7 +27,6 @@ import kotlinx.serialization.json.decodeFromJsonElement
|
||||
import kotlinx.serialization.json.int
|
||||
import kotlinx.serialization.json.jsonObject
|
||||
import kotlinx.serialization.json.jsonPrimitive
|
||||
import org.fairscan.app.domain.ExportQuality
|
||||
import org.fairscan.app.domain.Jpeg
|
||||
import org.fairscan.app.domain.PageMetadata
|
||||
import org.fairscan.app.domain.PageViewKey
|
||||
@@ -91,7 +90,7 @@ class ImageRepository(
|
||||
return when {
|
||||
metadataPages != null ->
|
||||
metadataPages
|
||||
.filter { processedImageFileName(it.id, it.colorMode) in filesOnDisk }
|
||||
.filter { processedImageFileName(it.id, it.colorMode, it.quadVersion) in filesOnDisk }
|
||||
.toMutableList()
|
||||
else ->
|
||||
filesOnDisk
|
||||
@@ -135,7 +134,7 @@ class ImageRepository(
|
||||
pages.pages().mapNotNull {
|
||||
runCatching {
|
||||
val manualRotation = Rotation.fromDegrees(it.manualRotationDegrees)
|
||||
ScanPage(it.id, manualRotation, it.colorMode, it.toMetadata())
|
||||
ScanPage(it.id, manualRotation, it.colorMode, it.quadVersion, it.toMetadata())
|
||||
}.getOrNull()
|
||||
}
|
||||
}
|
||||
@@ -143,7 +142,7 @@ class ImageRepository(
|
||||
suspend fun add(processed: Jpeg, source: Jpeg, metadata: PageMetadata, colorMode: ColorMode) =
|
||||
mutex.withLock {
|
||||
val id = "${System.currentTimeMillis()}"
|
||||
val key = PageViewKey(id, Rotation.R0, colorMode)
|
||||
val key = PageViewKey(id, Rotation.R0, colorMode, 0)
|
||||
processedImageFile(key).writeBytes(processed.bytes)
|
||||
sourceFile(id).writeBytes(source.bytes)
|
||||
pages.addOrReplace(
|
||||
@@ -162,18 +161,64 @@ class ImageRepository(
|
||||
}
|
||||
|
||||
suspend fun setColorMode(id: String, colorMode: ColorMode) {
|
||||
val key = PageViewKey(id, Rotation.R0, colorMode)
|
||||
val processedFile = processedImageFile(key)
|
||||
val metadata = mutex.withLock { pages.get(id)?.toMetadata() }
|
||||
updatePage(id) { page, metadata ->
|
||||
PageUpdate(
|
||||
updatedPage = page.copy(colorMode = colorMode),
|
||||
normalizedQuad = metadata.normalizedQuad,
|
||||
colorMode = colorMode,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun setUserQuad(id: String, newQuad: Quad) {
|
||||
updatePage(id) { page, metadata ->
|
||||
PageUpdate(
|
||||
updatedPage = page.copy(
|
||||
quadVersion = page.quadVersion + 1,
|
||||
userQuad = newQuad.toSerializable(),
|
||||
),
|
||||
normalizedQuad = newQuad,
|
||||
colorMode = page.colorMode ?: metadata.autoColorMode,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private data class PageUpdate(
|
||||
val updatedPage: PageV2,
|
||||
val normalizedQuad: Quad,
|
||||
val colorMode: ColorMode,
|
||||
)
|
||||
|
||||
private suspend fun updatePage(
|
||||
id: String,
|
||||
buildUpdate: (PageV2, PageMetadata) -> PageUpdate
|
||||
) {
|
||||
val page = mutex.withLock { pages.get(id) }
|
||||
val metadata = page?.toMetadata() ?: return
|
||||
val sourceFile = sourceFile(id)
|
||||
if (metadata == null || !sourceFile.exists())
|
||||
if (!sourceFile.exists())
|
||||
return
|
||||
|
||||
val update = buildUpdate(page, metadata)
|
||||
val key = PageViewKey(
|
||||
pageId = id,
|
||||
rotation = Rotation.R0,
|
||||
colorMode = update.colorMode,
|
||||
quadVersion = update.updatedPage.quadVersion
|
||||
)
|
||||
|
||||
val processedFile = processedImageFile(key)
|
||||
val job = processingJobs.computeIfAbsent(key) {
|
||||
scope.async(Dispatchers.IO) {
|
||||
if (!processedFile.exists()) {
|
||||
val sourceJpeg = Jpeg(sourceFile.readBytes())
|
||||
val processedJpeg = transformations.process(sourceJpeg, metadata, colorMode)
|
||||
val processedJpeg =
|
||||
transformations.process(
|
||||
sourceJpeg,
|
||||
normalizedQuad = update.normalizedQuad,
|
||||
baseRotation = metadata.baseRotation,
|
||||
colorMode = update.colorMode
|
||||
)
|
||||
processedFile.writeBytes(processedJpeg.bytes)
|
||||
}
|
||||
}
|
||||
@@ -185,7 +230,7 @@ class ImageRepository(
|
||||
}
|
||||
|
||||
mutex.withLock {
|
||||
pages.update(id) { it.copy(colorMode = colorMode) }
|
||||
pages.update(id) { update.updatedPage }
|
||||
saveMetadata()
|
||||
}
|
||||
}
|
||||
@@ -248,14 +293,18 @@ class ImageRepository(
|
||||
|
||||
// --- Other operations ---
|
||||
|
||||
private fun processedImageFileName(id: String, colorMode: ColorMode?) : String =
|
||||
if (colorMode == null)
|
||||
"${id}.jpg"
|
||||
else
|
||||
"${id}.${colorMode.name.lowercase()}.jpg"
|
||||
private fun processedImageFileName(id: String, colorMode: ColorMode?, quadVersion: Int) : String {
|
||||
val sb = StringBuilder(id)
|
||||
if (colorMode != null)
|
||||
sb.append(".").append(colorMode.name.lowercase())
|
||||
if (quadVersion > 0)
|
||||
sb.append(".q").append(quadVersion)
|
||||
sb.append(".jpg")
|
||||
return sb.toString()
|
||||
}
|
||||
|
||||
private fun processedImageFile(key: PageViewKey) : File =
|
||||
File(processedDir, processedImageFileName(key.pageId, key.colorMode))
|
||||
File(processedDir, processedImageFileName(key.pageId, key.colorMode, key.quadVersion))
|
||||
|
||||
private fun sourceFile(id: String): File =
|
||||
File(sourceDir, "$id.jpg")
|
||||
@@ -352,7 +401,7 @@ fun NormalizedQuad.toQuad(): Quad =
|
||||
fun PageV2.toMetadata(): PageMetadata? {
|
||||
if (quad == null || isColored == null) return null
|
||||
return PageMetadata(
|
||||
quad.toQuad(),
|
||||
(userQuad ?: quad).toQuad(),
|
||||
Rotation.fromDegrees(baseRotationDegrees),
|
||||
if (isColored) ColorMode.COLOR else ColorMode.GRAYSCALE
|
||||
)
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
package org.fairscan.app.data
|
||||
|
||||
import org.fairscan.app.domain.Jpeg
|
||||
import org.fairscan.app.domain.PageMetadata
|
||||
import org.fairscan.app.domain.Rotation
|
||||
import org.fairscan.imageprocessing.ColorMode
|
||||
import org.fairscan.imageprocessing.Quad
|
||||
|
||||
interface ImageTransformations {
|
||||
|
||||
@@ -24,6 +25,11 @@ interface ImageTransformations {
|
||||
|
||||
fun resizeToThumbnail(input: Jpeg): Jpeg
|
||||
|
||||
fun process(source: Jpeg, metadata: PageMetadata, colorMode: ColorMode): Jpeg
|
||||
fun process(
|
||||
source: Jpeg,
|
||||
normalizedQuad: Quad,
|
||||
baseRotation: Rotation,
|
||||
colorMode: ColorMode
|
||||
): Jpeg
|
||||
|
||||
}
|
||||
@@ -48,11 +48,11 @@ suspend fun jpegsForExport(
|
||||
JpegProvider {
|
||||
val source = imageRepository.source(page.id)
|
||||
val metadata = page.metadata
|
||||
val manualRotation = page.manualRotation
|
||||
val colorMode = page.colorMode
|
||||
if (source != null && metadata != null && colorMode != null) {
|
||||
val rotation = metadata.baseRotation.add(manualRotation)
|
||||
processedImage(source, metadata, rotation, colorMode, exportQuality)
|
||||
val rotation = page.totalRotation()
|
||||
val normalizedQuad = metadata.normalizedQuad
|
||||
processedImage(source, normalizedQuad, rotation, colorMode, exportQuality)
|
||||
}
|
||||
else
|
||||
jpeg(page, imageRepository)
|
||||
|
||||
@@ -27,19 +27,19 @@ data class ScanPage(
|
||||
val id: String,
|
||||
val manualRotation: Rotation,
|
||||
val colorMode: ColorMode?,
|
||||
val quadVersion: Int,
|
||||
val metadata: PageMetadata?,
|
||||
) {
|
||||
fun key(): PageViewKey = PageViewKey(id, manualRotation, colorMode)
|
||||
fun key() = PageViewKey(id, manualRotation, colorMode, quadVersion)
|
||||
fun totalRotation() = manualRotation.add(metadata?.baseRotation ?: Rotation.R0)
|
||||
}
|
||||
|
||||
data class PageViewKey(
|
||||
val pageId: String,
|
||||
val rotation: Rotation,
|
||||
val colorMode: ColorMode?,
|
||||
) {
|
||||
val saveKey: String get() = "$pageId-${rotation.degrees}-$colorMode"
|
||||
}
|
||||
|
||||
val quadVersion: Int,
|
||||
)
|
||||
enum class Rotation(val degrees: Int) {
|
||||
R0(0),
|
||||
R90(90),
|
||||
|
||||
@@ -73,14 +73,19 @@ class ImageProcessor(private val thumbnailSizePx: Int) : ImageTransformations {
|
||||
}
|
||||
}
|
||||
|
||||
override fun process(source: Jpeg, metadata: PageMetadata, colorMode: ColorMode): Jpeg {
|
||||
return processedImage(source, metadata, metadata.baseRotation, colorMode, ExportQuality.BALANCED)
|
||||
override fun process(
|
||||
source: Jpeg,
|
||||
normalizedQuad: Quad,
|
||||
baseRotation: Rotation,
|
||||
colorMode: ColorMode
|
||||
): Jpeg {
|
||||
return processedImage(source, normalizedQuad, baseRotation, colorMode, ExportQuality.BALANCED)
|
||||
}
|
||||
}
|
||||
|
||||
fun processedImage(
|
||||
source: Jpeg,
|
||||
metadata: PageMetadata,
|
||||
normalizedQuad: Quad,
|
||||
rotation: Rotation,
|
||||
colorMode: ColorMode,
|
||||
exportQuality: ExportQuality,
|
||||
@@ -90,7 +95,7 @@ fun processedImage(
|
||||
var page: Mat? = null
|
||||
try {
|
||||
sourceMat = source.toMat()
|
||||
val quad = metadata.normalizedQuad.scaledTo(1, 1, sourceMat.width(), sourceMat.height())
|
||||
val quad = normalizedQuad.scaledTo(1, 1, sourceMat.width(), sourceMat.height())
|
||||
page = extractDocument(sourceMat, quad, rotationDegrees, colorMode, exportQuality.maxPixels)
|
||||
return Jpeg.fromMat(page, exportQuality.jpegQuality)
|
||||
} finally {
|
||||
|
||||
@@ -30,7 +30,7 @@ fun dummyNavigation(): Navigation {
|
||||
|
||||
fun fakeDocument(pageIds: ImmutableList<String>, context: Context): DocumentUiModel {
|
||||
val pageKeys = pageIds.map {
|
||||
PageThumbnail(PageViewKey(it, Rotation.R0, ColorMode.COLOR), fakeImage(it, context))
|
||||
PageThumbnail(PageViewKey(it, Rotation.R0, ColorMode.COLOR, 0), fakeImage(it, context))
|
||||
}.toImmutableList()
|
||||
return DocumentUiModel(pageKeys)
|
||||
}
|
||||
|
||||
@@ -370,7 +370,7 @@ fun DocumentScreenPreview() {
|
||||
listOf(1, 2).map { "gallica.bnf.fr-bpt6k5530456s-$it" }.toImmutableList(),
|
||||
LocalContext.current
|
||||
)
|
||||
val key = PageViewKey("123", Rotation.R0, null)
|
||||
val key = PageViewKey("123", Rotation.R0, null, 0)
|
||||
DocumentScreen(
|
||||
uiState = DocumentUiState(1, CurrentPageUiState(key,image, COLOR, true), document),
|
||||
navigation = dummyNavigation(),
|
||||
|
||||
@@ -69,7 +69,7 @@ fun EditPageScreen(
|
||||
onLoad: (String) -> Unit,
|
||||
initState: CropInitState,
|
||||
navigation: Navigation,
|
||||
onUpdatePageQuad: (String, Quad, onComplete: () -> Unit) -> Unit,
|
||||
onUpdatePageQuad: (Quad) -> Unit,
|
||||
) {
|
||||
val state = remember { EditPageScreenState() }
|
||||
val quadHandler = remember { QuadEditingHandler() }
|
||||
@@ -125,20 +125,8 @@ fun EditPageScreen(
|
||||
.padding(16.dp)
|
||||
.windowInsetsPadding(WindowInsets.safeDrawing),
|
||||
onConfirm = {
|
||||
/*
|
||||
val quad = state.editableQuad
|
||||
if (quad != null) {
|
||||
// Reverse the total rotation to get back to original source image coordinates
|
||||
val rotateIterations = (4 - totalRotation.value.degrees / 90) % 4
|
||||
val originalQuad = quad.rotate90(rotateIterations, ImageSize(1, 1))
|
||||
onUpdatePageQuad(pageId, originalQuad) {
|
||||
navigation.back()
|
||||
}
|
||||
state.setInitialQuad(quad)
|
||||
} else {
|
||||
navigation.back()
|
||||
}
|
||||
*/
|
||||
state.editableQuad?.let { onUpdatePageQuad(it) }
|
||||
navigation.back()
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -336,7 +324,7 @@ fun EditPageScreenPreview() {
|
||||
onLoad = {},
|
||||
initState = CropInitState.Ready("123",dummyImage, quad),
|
||||
navigation = dummyNavigation(),
|
||||
onUpdatePageQuad = { _,_,_ -> },
|
||||
onUpdatePageQuad = { _ -> },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import org.assertj.core.api.Assertions.assertThat
|
||||
import org.fairscan.app.domain.Jpeg
|
||||
import org.fairscan.app.domain.PageMetadata
|
||||
import org.fairscan.app.domain.PageViewKey
|
||||
import org.fairscan.app.domain.Rotation
|
||||
import org.fairscan.app.domain.Rotation.R0
|
||||
import org.fairscan.app.domain.Rotation.R180
|
||||
import org.fairscan.app.domain.Rotation.R270
|
||||
@@ -62,7 +63,7 @@ class ImageRepositoryTest {
|
||||
fun repo(
|
||||
rotate: (Jpeg, Int) -> Jpeg = { input, _ -> input },
|
||||
resizeToThumbnail: (Jpeg) -> Jpeg = { input -> jpeg(input.bytes[0]) },
|
||||
process: (Jpeg, PageMetadata, ColorMode) -> Jpeg = { _, _, _ ->
|
||||
process: (Jpeg, Quad, Rotation, ColorMode) -> Jpeg = { _, _, _, _ ->
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
): ImageRepository {
|
||||
@@ -71,8 +72,12 @@ class ImageRepositoryTest {
|
||||
rotate(input, rotationDegrees)
|
||||
override fun resizeToThumbnail(input: Jpeg): Jpeg =
|
||||
resizeToThumbnail(input)
|
||||
override fun process(source: Jpeg, metadata: PageMetadata, colorMode: ColorMode): Jpeg =
|
||||
process(source, metadata, colorMode)
|
||||
override fun process(
|
||||
source: Jpeg,
|
||||
normalizedQuad: Quad,
|
||||
baseRotation: Rotation,
|
||||
colorMode: ColorMode
|
||||
): Jpeg = process(source, normalizedQuad, baseRotation, colorMode)
|
||||
}
|
||||
|
||||
return ImageRepository(getFilesDir(), transformations, testScope)
|
||||
@@ -86,7 +91,7 @@ class ImageRepositoryTest {
|
||||
repo.add(jpeg, jpeg(51), metadata1, COLOR)
|
||||
assertThat(repo.imageIds()).hasSize(1)
|
||||
val id = repo.imageIds()[0]
|
||||
val key = PageViewKey(id, R0, COLOR)
|
||||
val key = PageViewKey(id, R0, COLOR, 0)
|
||||
assertThat(repo.jpegBytes(key)).isEqualTo(jpeg)
|
||||
assertThat(repo.getThumbnail(key)?.bytes).isEqualTo(byteArrayOf(101))
|
||||
|
||||
@@ -153,7 +158,7 @@ class ImageRepositoryTest {
|
||||
File(processedDir(), "1-90.jpg").writeBytes(bytes)
|
||||
val repo = repo()
|
||||
assertThat(repo.imageIds()).containsExactly("1")
|
||||
assertThat(repo.jpegBytes(PageViewKey("1", R0, null))?.bytes).isEqualTo(bytes)
|
||||
assertThat(repo.jpegBytes(PageViewKey("1", R0, null, 0))?.bytes).isEqualTo(bytes)
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -182,14 +187,14 @@ class ImageRepositoryTest {
|
||||
File(processedDir(), "1-90.jpg").writeBytes(bytes)
|
||||
val repo = repo()
|
||||
assertThat(repo.imageIds()).containsExactly("1")
|
||||
assertThat(repo.jpegBytes(PageViewKey("1", R0, null))?.bytes).isEqualTo(bytes)
|
||||
assertThat(repo.jpegBytes(PageViewKey("1", R0, null, 0))?.bytes).isEqualTo(bytes)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `should return null on invalid id`() = runTest {
|
||||
val repo = repo()
|
||||
assertThat(repo.imageIds()).isEmpty()
|
||||
assertThat(repo.jpegBytes(PageViewKey("x", R0, COLOR))).isNull()
|
||||
assertThat(repo.jpegBytes(PageViewKey("x", R0, COLOR, 0))).isNull()
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -239,7 +244,7 @@ class ImageRepositoryTest {
|
||||
fun setColorMode_should_process_and_update_metadata() = runTest {
|
||||
val jpeg1 = jpeg(10)
|
||||
val repo = repo(
|
||||
process = { jpeg ,meta, mode ->
|
||||
process = { _, _ , _, mode ->
|
||||
assertThat(mode).isEqualTo(GRAYSCALE)
|
||||
jpeg(41)
|
||||
}
|
||||
@@ -249,7 +254,7 @@ class ImageRepositoryTest {
|
||||
val id = repo.pages().first().id
|
||||
repo.setColorMode(id, GRAYSCALE)
|
||||
assertThat(repo.pages().first().colorMode).isEqualTo(GRAYSCALE)
|
||||
val key = PageViewKey(id, R0, GRAYSCALE)
|
||||
val key = PageViewKey(id, R0, GRAYSCALE, 0)
|
||||
assertThat(repo.jpegBytes(key)?.bytes).isEqualTo(byteArrayOf(41))
|
||||
}
|
||||
|
||||
@@ -257,7 +262,7 @@ class ImageRepositoryTest {
|
||||
fun setColorMode_should_not_run_twice_in_parallel() = runTest {
|
||||
var processCalls = 0
|
||||
val repo = repo(
|
||||
process = { _, _, _ ->
|
||||
process = { _, _, _, _ ->
|
||||
processCalls++
|
||||
runBlocking { delay(10) }
|
||||
jpeg(1)
|
||||
@@ -269,7 +274,7 @@ class ImageRepositoryTest {
|
||||
launch { repo.setColorMode(id, GRAYSCALE) }
|
||||
launch { repo.setColorMode(id, GRAYSCALE) }
|
||||
}
|
||||
val key = PageViewKey(id, R0, GRAYSCALE)
|
||||
val key = PageViewKey(id, R0, GRAYSCALE, 0)
|
||||
assertThat(repo.jpegBytes(key)?.bytes).isEqualTo(byteArrayOf(1))
|
||||
assertThat(processCalls).isEqualTo(1)
|
||||
}
|
||||
@@ -307,11 +312,11 @@ class ImageRepositoryTest {
|
||||
fun metadata() {
|
||||
val quad = quad1.toSerializable()
|
||||
|
||||
assertThat(PageV2("1", 0, 0, null,true).toMetadata()).isNull()
|
||||
assertThat(PageV2("1", 0, 0, quad, null).toMetadata()).isNull()
|
||||
assertThat(PageV2("1", 0, 0, quad = null, isColored = true).toMetadata()).isNull()
|
||||
assertThat(PageV2("1", 0, 0, quad).toMetadata()).isNull()
|
||||
|
||||
listOf(true, false).forEach { isColored ->
|
||||
val metadata = PageV2("1", 0, 0, quad, isColored).toMetadata()
|
||||
val metadata = PageV2("1", 0, 0, quad, isColored = isColored).toMetadata()
|
||||
assertThat(metadata).isNotNull()
|
||||
assertThat(metadata!!.autoColorMode).isEqualTo(
|
||||
if (isColored) COLOR else GRAYSCALE
|
||||
|
||||
Reference in New Issue
Block a user