Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,34 @@ class RealImageLoaderAndroidTest {
srcHeight = 4965,
dstWidth = maxBitmapSize.width.pxOrElse { throw IllegalStateException() },
dstHeight = maxBitmapSize.height.pxOrElse { throw IllegalStateException() },
scale = Scale.FIT
scale = Scale.FIT,
maxSize = maxBitmapSize,
)
val expectedWidth = (multiplier * 9052).roundToInt()
val expectedHeight = (multiplier * 4965).roundToInt()
assertTrue(image.bitmap.width in expectedWidth - 1..expectedWidth + 1)
assertTrue(image.bitmap.height in expectedHeight - 1..expectedHeight + 1)
}

@Test
fun veryLargeImageWithFill() = runTest {
val request = ImageRequest.Builder(context)
.data(R.drawable.very_large)
.scale(Scale.FILL)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test with FILL scaling.

.build()
val result = imageLoader.execute(request)
if (result is ErrorResult) throw result.throwable

assertIs<SuccessResult>(result)
val image = assertIs<BitmapImage>(result.image)
val maxBitmapSize = Extras.Key.maxBitmapSize.default
val multiplier = DecodeUtils.computeSizeMultiplier(
srcWidth = 9052,
srcHeight = 4965,
dstWidth = maxBitmapSize.width.pxOrElse { throw IllegalStateException() },
dstHeight = maxBitmapSize.height.pxOrElse { throw IllegalStateException() },
scale = Scale.FILL,
maxSize = maxBitmapSize,
)
val expectedWidth = (multiplier * 9052).roundToInt()
val expectedHeight = (multiplier * 4965).roundToInt()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class BitmapFactoryDecoder(
dstWidth = dstWidth.toDouble(),
dstHeight = dstHeight.toDouble(),
scale = options.scale,
maxSize = options.maxBitmapSize,
)

// Only upscale the image if the options require an exact size.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import coil3.request.colorSpace
import coil3.request.maxBitmapSize
import coil3.request.premultipliedAlpha
import coil3.size.Precision
import coil3.size.Size
import coil3.util.component1
import coil3.util.component2
import coil3.util.isHardware
Expand Down Expand Up @@ -60,6 +61,7 @@ class StaticImageDecoder(
dstWidth = dstWidth,
dstHeight = dstHeight,
scale = options.scale,
maxSize = options.maxBitmapSize,
)

// Set the target size if the image is larger than the requested dimensions
Expand Down
48 changes: 43 additions & 5 deletions coil-core/src/commonMain/kotlin/coil3/decode/DecodeUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,27 @@ object DecodeUtils {
dstWidth: Int,
dstHeight: Int,
scale: Scale,
maxSize: Size = Size.ORIGINAL,
): Double {
val widthPercent = dstWidth / srcWidth.toDouble()
val heightPercent = dstHeight / srcHeight.toDouble()
return when (scale) {
val srcWidthDouble = srcWidth.toDouble()
val srcHeightDouble = srcHeight.toDouble()
val widthPercent = dstWidth / srcWidthDouble
val heightPercent = dstHeight / srcHeightDouble
var percent = when (scale) {
Scale.FILL -> maxOf(widthPercent, heightPercent)
Scale.FIT -> minOf(widthPercent, heightPercent)
}
if (maxSize.width is Dimension.Pixels) {
val maxWidth = maxSize.width.px
val maxWidthPercent = maxWidth / srcWidthDouble
percent = percent.coerceAtMost(maxWidthPercent)
}
if (maxSize.height is Dimension.Pixels) {
val maxHeight = maxSize.height.px
val maxHeightPercent = maxHeight / srcHeightDouble
percent = percent.coerceAtMost(maxHeightPercent)
}
return percent
}

/** @see computeSizeMultiplier */
Expand All @@ -60,13 +74,25 @@ object DecodeUtils {
dstWidth: Float,
dstHeight: Float,
scale: Scale,
maxSize: Size = Size.ORIGINAL,
): Float {
val widthPercent = dstWidth / srcWidth
val heightPercent = dstHeight / srcHeight
return when (scale) {
var percent = when (scale) {
Scale.FILL -> maxOf(widthPercent, heightPercent)
Scale.FIT -> minOf(widthPercent, heightPercent)
}
if (maxSize.width is Dimension.Pixels) {
val maxWidth = maxSize.width.px
val maxWidthPercent = maxWidth / srcWidth
percent = percent.coerceAtMost(maxWidthPercent)
}
if (maxSize.height is Dimension.Pixels) {
val maxHeight = maxSize.height.px
val maxHeightPercent = maxHeight / srcHeight
percent = percent.coerceAtMost(maxHeightPercent)
}
return percent
}

/** @see computeSizeMultiplier */
Expand All @@ -77,13 +103,25 @@ object DecodeUtils {
dstWidth: Double,
dstHeight: Double,
scale: Scale,
maxSize: Size = Size.ORIGINAL,
): Double {
val widthPercent = dstWidth / srcWidth
val heightPercent = dstHeight / srcHeight
return when (scale) {
var percent = when (scale) {
Scale.FILL -> maxOf(widthPercent, heightPercent)
Scale.FIT -> minOf(widthPercent, heightPercent)
}
if (maxSize.width is Dimension.Pixels) {
val maxWidth = maxSize.width.px
val maxWidthPercent = maxWidth / srcWidth
percent = percent.coerceAtMost(maxWidthPercent)
}
if (maxSize.height is Dimension.Pixels) {
val maxHeight = maxSize.height.px
val maxHeightPercent = maxHeight / srcHeight
percent = percent.coerceAtMost(maxHeightPercent)
}
return percent
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ internal fun Bitmap.Companion.makeFromImage(
dstWidth = dstWidth,
dstHeight = dstHeight,
scale = options.scale,
maxSize = options.maxBitmapSize,
)

// Only upscale the image if the options require an exact size.
Expand Down
1 change: 1 addition & 0 deletions coil-gif/src/main/java/coil3/gif/AnimatedImageDecoder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ class AnimatedImageDecoder(
dstWidth = dstWidth,
dstHeight = dstHeight,
scale = options.scale,
maxSize = options.maxBitmapSize,
)

// Set the target size if the image is larger than the requested dimensions
Expand Down
1 change: 1 addition & 0 deletions coil-svg/src/commonMain/kotlin/coil3/svg/SvgDecoder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ class SvgDecoder(
dstWidth = dstWidth.toFloat(),
dstHeight = dstHeight.toFloat(),
scale = options.scale,
maxSize = options.maxBitmapSize,
)
bitmapWidth = (multiplier * svgWidth).toInt()
bitmapHeight = (multiplier * svgHeight).toInt()
Expand Down
1 change: 1 addition & 0 deletions coil-video/src/main/java/coil3/video/VideoFrameDecoder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class VideoFrameDecoder(
dstWidth = dstWidth,
dstHeight = dstHeight,
scale = options.scale,
maxSize = options.maxBitmapSize,
)
val scale = if (options.precision == Precision.INEXACT) {
rawScale.coerceAtMost(1.0)
Expand Down
Loading