diff --git a/examples/blur.png b/examples/blur.png index a56cd1b..09279df 100644 Binary files a/examples/blur.png and b/examples/blur.png differ diff --git a/examples/shadow.png b/examples/shadow.png index 4bcbae3..ef172e6 100644 Binary files a/examples/shadow.png and b/examples/shadow.png differ diff --git a/src/pixie/images.nim b/src/pixie/images.nim index aecc670..9b98612 100644 --- a/src/pixie/images.nim +++ b/src/pixie/images.nim @@ -475,10 +475,10 @@ proc blur*( template rgbx(values: array[4, uint32]): ColorRGBX = rgbx( - (values[0] div 1024 div 255).uint8, - (values[1] div 1024 div 255).uint8, - (values[2] div 1024 div 255).uint8, - (values[3] div 1024 div 255).uint8 + (values[0] div 256 div 255).uint8, + (values[1] div 256 div 255).uint8, + (values[2] div 256 div 255).uint8, + (values[3] div 256 div 255).uint8 ) # Blur in the X direction. Store with dimensions swapped for reading later. @@ -488,13 +488,10 @@ proc blur*( var values: array[4, uint32] for xx in x - radius ..< min(x + radius, 0): values += outOfBounds * kernel[xx - x + radius] - for xx in max(x - radius, 0) .. min(x + radius, image.width - 1): values += image.getRgbaUnsafe(xx, y) * kernel[xx - x + radius] - for xx in max(x - radius, image.width) .. x + radius: values += outOfBounds * kernel[xx - x + radius] - blurX.setRgbaUnsafe(y, x, rgbx(values)) # Blur in the Y direction. @@ -503,13 +500,10 @@ proc blur*( var values: array[4, uint32] for yy in y - radius ..< min(y + radius, 0): values += outOfBounds * kernel[yy - y + radius] - for yy in max(y - radius, 0) .. min(y + radius, image.height - 1): values += blurX.getRgbaUnsafe(yy, x) * kernel[yy - y + radius] - for yy in max(y - radius, image.height) .. y + radius: values += outOfBounds * kernel[yy - y + radius] - image.setRgbaUnsafe(x, y, rgbx(values)) proc newMask*(image: Image): Mask {.raises: [PixieError].} = diff --git a/src/pixie/internal.nim b/src/pixie/internal.nim index 0fe2894..411cffd 100644 --- a/src/pixie/internal.nim +++ b/src/pixie/internal.nim @@ -3,9 +3,9 @@ import chroma, vmath when defined(amd64) and not defined(pixieNoSimd): import nimsimd/sse2 -proc gaussianKernel*(radius: int): seq[uint32] {.raises: [].} = +proc gaussianKernel*(radius: int): seq[uint16] {.raises: [].} = ## Compute lookup table for 1d Gaussian kernel. - ## Values are [0, 255] * 1024. + ## Values are [0, 255] * 256. result.setLen(radius * 2 + 1) var @@ -19,9 +19,8 @@ proc gaussianKernel*(radius: int): seq[uint32] {.raises: [].} = total += a for step in -radius .. radius: floats[step + radius] = floats[step + radius] / total - for i, f in floats: - result[i] = round(f * 255 * 1024).uint32 + result[i] = round(f * 255 * 256).uint16 proc applyOpacity*(color: ColorRGBX, opacity: float32): ColorRGBX {.raises: [].} = if opacity == 0: diff --git a/src/pixie/masks.nim b/src/pixie/masks.nim index 9eafd92..9bc39e8 100644 --- a/src/pixie/masks.nim +++ b/src/pixie/masks.nim @@ -275,30 +275,24 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) {.raises: [Pixie for x in 0 ..< mask.width: var value: uint32 for xx in x - radius ..< min(x + radius, 0): - value += outOfBounds * kernel[xx - x + radius] - + value += outOfBounds * kernel[xx - x + radius].uint32 for xx in max(x - radius, 0) .. min(x + radius, mask.width - 1): - value += mask.getValueUnsafe(xx, y) * kernel[xx - x + radius] - + value += mask.getValueUnsafe(xx, y) * kernel[xx - x + radius].uint32 for xx in max(x - radius, mask.width) .. x + radius: - value += outOfBounds * kernel[xx - x + radius] - - blurX.setValueUnsafe(y, x, (value div 1024 div 255).uint8) + value += outOfBounds * kernel[xx - x + radius].uint32 + blurX.setValueUnsafe(y, x, (value div 256 div 255).uint8) # Blur in the Y direction and modify image. for y in 0 ..< mask.height: for x in 0 ..< mask.width: var value: uint32 for yy in y - radius ..< min(y + radius, 0): - value += outOfBounds * kernel[yy - y + radius] - + value += outOfBounds * kernel[yy - y + radius].uint32 for yy in max(y - radius, 0) .. min(y + radius, mask.height - 1): - value += blurX.getValueUnsafe(yy, x) * kernel[yy - y + radius] - + value += blurX.getValueUnsafe(yy, x) * kernel[yy - y + radius].uint32 for yy in max(y - radius, mask.height) .. y + radius: - value += outOfBounds * kernel[yy - y + radius] - - mask.setValueUnsafe(x, y, (value div 1024 div 255).uint8) + value += outOfBounds * kernel[yy - y + radius].uint32 + mask.setValueUnsafe(x, y, (value div 256 div 255).uint8) when defined(release): {.pop.} diff --git a/tests/benchmark_images_blur.nim b/tests/benchmark_images_blur.nim index f04d215..b1a41c5 100644 --- a/tests/benchmark_images_blur.nim +++ b/tests/benchmark_images_blur.nim @@ -41,13 +41,10 @@ proc blurSlower*( var values: array[4, uint32] for xx in x - radius ..< min(x + radius, 0): values += outOfBounds * kernel[xx - x + radius] - for xx in max(x - radius, 0) .. min(x + radius, image.width - 1): values += image.getRgbaUnsafe(xx, y) * kernel[xx - x + radius] - for xx in max(x - radius, image.width) .. x + radius: values += outOfBounds * kernel[xx - x + radius] - blurX.setRgbaUnsafe(x, y, rgbx(values)) # Blur in the Y direction. @@ -56,13 +53,10 @@ proc blurSlower*( var values: array[4, uint32] for yy in y - radius ..< min(y + radius, 0): values += outOfBounds * kernel[yy - y + radius] - for yy in max(y - radius, 0) .. min(y + radius, image.height - 1): values += blurX.getRgbaUnsafe(x, yy) * kernel[yy - y + radius] - for yy in max(y - radius, image.height) .. y + radius: values += outOfBounds * kernel[yy - y + radius] - image.setRgbaUnsafe(x, y, rgbx(values)) let image = newImage(1920, 1080) diff --git a/tests/images/imageblur20.png b/tests/images/imageblur20.png index 9704d36..e85f277 100644 Binary files a/tests/images/imageblur20.png and b/tests/images/imageblur20.png differ diff --git a/tests/images/imageblur20oob.png b/tests/images/imageblur20oob.png index d283fc5..8d9e1e4 100644 Binary files a/tests/images/imageblur20oob.png and b/tests/images/imageblur20oob.png differ diff --git a/tests/images/maskblur20.png b/tests/images/maskblur20.png index bab2143..0b67600 100644 Binary files a/tests/images/maskblur20.png and b/tests/images/maskblur20.png differ