blur kernel 16 bits
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 89 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.2 KiB |
|
@ -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].} =
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.}
|
||||
|
|
|
@ -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)
|
||||
|
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 4 KiB After Width: | Height: | Size: 4 KiB |
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.2 KiB |