Skip to content

Commit

Permalink
Fix grayscale jpeg rendering colors. (#1829)
Browse files Browse the repository at this point in the history
* Refactor out part of the sandbox code so it can be used for Jvm entrypoint.

* Update entrypoint name.

* Fix grayscale jpeg rendering.

* Remove unused code (#1825)

* remove commented code

* remove unused code

* remove unused code

* remove unused code

---------

Co-authored-by: Alexandre Mommers <[email protected]>

* Convert buildSrc to using kts (#1830)

* Delete build.gradle.old (#1831)

* enable tests on release branches (#1833)

* Fix grayscale jpeg rendering.

* Try fix test-native-macos.

* Try fix test-native-macos. pt.2

---------

Co-authored-by: Alexandre Mommers <[email protected]>
Co-authored-by: Alexandre Mommers <[email protected]>
  • Loading branch information
3 people committed Aug 11, 2023
1 parent d2706e0 commit 2d6152c
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 91 deletions.
185 changes: 95 additions & 90 deletions korge/src/jvmMain/kotlin/korlibs/korge/testing/testing_utils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ inline fun korgeScreenshotTestV2(
settings: KorgeScreenshotValidationSettings = KorgeScreenshotValidationSettings(),
crossinline callback: suspend Stage.(korgeScreenshotTester: KorgeScreenshotTester) -> Unit = {},
) {
System.setProperty("java.awt.headless", "false")
// System.setProperty("java.awt.headless", "false")
val throwable = Throwable()
val testClassName = throwable.stackTrace[0].className
val testMethodName = throwable.stackTrace[0].methodName
Expand Down Expand Up @@ -65,113 +65,118 @@ inline fun korgeScreenshotTestV2(
// No diffs, no need to show UI to update goldens.
if (resultsWithErrors.isEmpty()) return@suspendTest

val config = Korge(
backgroundColor = Colors.LIGHTGRAY,
windowSize = Size(1280, 720),
virtualSize = Size(700, 480),
main = {
views.gameWindow.exitProcessOnExit = false

uiScrollable(size = Size(700.0, 480.0)) { uiScrollable ->
uiScrollable.backgroundColor = Colors.LIGHTGRAY
var prevContainer: Container? = null
resultsWithErrors.forEach { testResult ->
val viewsToAlign = mutableListOf<View>()
container {
viewsToAlign += text("Test method name: ${results.testMethodName}")
// val testResultSection = container {
viewsToAlign += text("Golden name: ${testResult.goldenName}")
viewsToAlign += container {
val fn = { headerText: String, bitmap: Bitmap? ->
container {
val headerText = if (bitmap == null) {
text(headerText)
} else {
text("$headerText (${bitmap.size.width.toInt()} x ${bitmap.size.height.toInt()})")
}

val rect =
solidRect(
320,
240,
color = Colors.BLACK.withAd(0.75)
) {
alignTopToBottomOf(headerText)
println("Diffs found...")
val interactive = Environment["INTERACTIVE_SCREENSHOT"] == "true"
if (interactive) {
val config = Korge(
backgroundColor = Colors.LIGHTGRAY,
windowSize = Size(1280, 720),
virtualSize = Size(700, 480),
main = {
views.gameWindow.exitProcessOnExit = false

uiScrollable(size = Size(700.0, 480.0)) { uiScrollable ->
uiScrollable.backgroundColor = Colors.LIGHTGRAY
var prevContainer: Container? = null
resultsWithErrors.forEach { testResult ->
val viewsToAlign = mutableListOf<View>()
container {
viewsToAlign += text("Test method name: ${results.testMethodName}")
// val testResultSection = container {
viewsToAlign += text("Golden name: ${testResult.goldenName}")
viewsToAlign += container {
val fn = { headerText: String, bitmap: Bitmap? ->
container {
val headerText = if (bitmap == null) {
text(headerText)
} else {
text("$headerText (${bitmap.size.width.toInt()} x ${bitmap.size.height.toInt()})")
}
if (bitmap == null) {
text("Deleted") {
centerOn(rect)
}
} else {
image(bitmap).apply {
scaleWhileMaintainingAspect(
ScalingOption.ByWidthAndHeight(
310.0,
230.0

val rect =
solidRect(
320,
240,
color = Colors.BLACK.withAd(0.75)
) {
alignTopToBottomOf(headerText)
}
if (bitmap == null) {
text("Deleted") {
centerOn(rect)
}
} else {
image(bitmap).apply {
scaleWhileMaintainingAspect(
ScalingOption.ByWidthAndHeight(
310.0,
230.0
)
)
)
centerOn(rect)
centerOn(rect)
}
}
}

}
}
val oldImage = fn("Old Image", testResult.oldBitmap)
val newImage =
fn("New Image", testResult.newBitmap).apply {
alignLeftToRightOf(oldImage, padding = 5.0)
}
}
val oldImage = fn("Old Image", testResult.oldBitmap)
val newImage =
fn("New Image", testResult.newBitmap).apply {
alignLeftToRightOf(oldImage, padding = 5.0)
}
}

val separator = "\n * "
viewsToAlign += container {
val textResultString = testResult.validationErrors.joinToString(
separator = separator,
prefix = separator
) {
it.errorMessaage
val separator = "\n * "
viewsToAlign += container {
val textResultString = testResult.validationErrors.joinToString(
separator = separator,
prefix = separator
) {
it.errorMessaage
}
text("Validation errors:$textResultString")
}
text("Validation errors:$textResultString")
}

viewsToAlign += uiButton("Accept change?") {
centerXOn(this@container)
onClick {
val goldenFileNameWithExt =
context.makeGoldenFileNameWithExtension(testResult.goldenName)
if (testResult.newBitmap != null) {
context.tempGoldensVfs[goldenFileNameWithExt].copyTo(
context.testGoldensVfs[goldenFileNameWithExt]
)
} else {
// Bitmap was deleted
context.testGoldensVfs[goldenFileNameWithExt].delete()
viewsToAlign += uiButton("Accept change?") {
centerXOn(this@container)
onClick {
val goldenFileNameWithExt =
context.makeGoldenFileNameWithExtension(testResult.goldenName)
if (testResult.newBitmap != null) {
context.tempGoldensVfs[goldenFileNameWithExt].copyTo(
context.testGoldensVfs[goldenFileNameWithExt]
)
} else {
// Bitmap was deleted
context.testGoldensVfs[goldenFileNameWithExt].delete()
}
disable()
}
disable()
}
}

viewsToAlign.windowed(2) {
it[1].alignTopToBottomOf(it[0])
}
viewsToAlign.windowed(2) {
it[1].alignTopToBottomOf(it[0])
}

val sectionBg =
solidRect(scaledWidth, scaledHeight, Colors.DARKSLATEGRAY)
sendChildToBack(sectionBg)
val sectionBg =
solidRect(scaledWidth, scaledHeight, Colors.DARKSLATEGRAY)
sendChildToBack(sectionBg)

centerXOnStage()
centerXOnStage()

if (prevContainer != null) {
alignTopToBottomOf(prevContainer!!, padding = 10.0)
if (prevContainer != null) {
alignTopToBottomOf(prevContainer!!, padding = 10.0)
}
prevContainer = this
}
prevContainer = this
}

}
}
}

})
config.start()

})
config.start()
} else {
println("Diffs found... Update goldens with INTERACTIVE_SCREENSHOT=true.")
}
}
}
10 changes: 10 additions & 0 deletions korge/src/jvmTest/kotlin/korlibs/korge/image/KorgeImageTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ package korlibs.korge.image
import korlibs.image.format.*
import korlibs.io.async.*
import korlibs.io.file.std.*
import korlibs.korge.Korge
import korlibs.korge.testing.korgeScreenshotTestV2
import korlibs.korge.view.image
import korlibs.math.geom.slice.*
import kotlin.test.*

Expand All @@ -14,4 +17,11 @@ class KorgeImageTest {
imageInfo?.orientation = SliceOrientation.MIRROR_HORIZONTAL_ROTATE_0
assertEquals(SliceOrientation(rotation = SliceRotation.R0, flipX = true), imageInfo?.orientationSure)
}

@Test
fun renderGrayscaleJpegImage() = korgeScreenshotTestV2(Korge()) {
val img = image(resourcesVfs["img1_grayscale.jpg"].readBitmapNative())
it.recordGolden(img, "grayscale_jpg")
it.endTest()
}
}
Binary file added korge/src/jvmTest/resources/img1_grayscale.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion korim/src/jvmMain/kotlin/korlibs/image/awt/AwtExt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,9 @@ fun ImageIOReadFormat(s: InputStream, type: Int = AWT_INTERNAL_IMAGE_TYPE_PRE):
} finally {
reader.dispose()
}
}.cloneIfRequired(type = type) // Clone is not required since just read directly in the right format
}
// NOTE: This line seems to mess up grayscale jpeg images.
//.cloneIfRequired(type = type) // Clone is not required since just read directly in the right format

fun awtReadImage(data: ByteArray): BufferedImage = ImageIOReadFormat(ByteArrayInputStream(data))

Expand Down

0 comments on commit 2d6152c

Please sign in to comment.