diff --git a/src/pixie/images.nim b/src/pixie/images.nim index dae03cb..b11de60 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -218,13 +218,15 @@ proc toAlphy*(image: Image) = image.data[j] = c proc fromAlphy*(image: Image) = - ## Converts an image to from premultiplied alpha to straight. + ## Converts an image from premultiplied alpha to straight alpha. + ## This is expensive for large images. for c in image.data.mitems: - if c.a == 0: + if c.a == 0 or c.a == 255: continue - c.r = ((c.r.uint32 * 255) div c.a.uint32).uint8 - c.g = ((c.g.uint32 * 255) div c.a.uint32).uint8 - c.b = ((c.b.uint32 * 255) div c.a.uint32).uint8 + let multiplier = ((255 / c.a.float32) * 255).uint32 + c.r = ((c.r.uint32 * multiplier) div 255).uint8 + c.g = ((c.g.uint32 * multiplier) div 255).uint8 + c.b = ((c.b.uint32 * multiplier) div 255).uint8 proc draw*(a, b: Image, mat: Mat3, blendMode = bmNormal) proc draw*(a, b: Image, pos = vec2(0, 0), blendMode = bmNormal) {.inline.} diff --git a/tests/benchmark_images.nim b/tests/benchmark_images.nim index e50e366..e7b10fb 100644 --- a/tests/benchmark_images.nim +++ b/tests/benchmark_images.nim @@ -8,8 +8,8 @@ timeIt "fill": keep(a) timeIt "fill_rgba": - a.fill(rgba(63, 127, 191, 255)) - doAssert a[0, 0] == rgba(63, 127, 191, 255) + a.fill(rgba(63, 127, 191, 191)) + doAssert a[0, 0] == rgba(63, 127, 191, 191) keep(a) timeIt "subImage": @@ -26,3 +26,11 @@ timeIt "applyOpacity": timeIt "sharpOpacity": a.sharpOpacity() keep(a) + +a.fill(rgba(63, 127, 191, 191)) + +timeIt "toAlphy": + a.toAlphy() + +timeIt "fromAlphy": + a.fromAlphy() diff --git a/tests/test_images.nim b/tests/test_images.nim index 30a809d..889b609 100644 --- a/tests/test_images.nim +++ b/tests/test_images.nim @@ -26,7 +26,7 @@ block: let image = newImage(10, 10) image.fill(rgba(128, 0, 0, 128)) image.fromAlphy() - doAssert image[9, 9] == rgba(255, 0, 0, 128) + doAssert image[9, 9] == rgba(254, 0, 0, 128) block: let