blur performance improved
This commit is contained in:
parent
117cad90b2
commit
39d316d0d7
|
@ -354,22 +354,38 @@ proc blur*(image: Image, radius: float32) =
|
|||
for y in 0 ..< image.height:
|
||||
for x in 0 ..< image.width:
|
||||
var values: array[4, uint32]
|
||||
for xb in -radius .. radius:
|
||||
let
|
||||
sample = image[x + xb, y]
|
||||
a = lookup[xb + radius].uint32
|
||||
values += sample * a
|
||||
if image.inside(x - radius, y) and image.inside(x + radius, y):
|
||||
for step in -radius .. radius:
|
||||
let
|
||||
sample = image.getRgbaUnsafe(x + step, y)
|
||||
a = lookup[step + radius].uint32
|
||||
values += sample * a
|
||||
else:
|
||||
for step in -radius .. radius:
|
||||
let
|
||||
sample = image[x + step, y]
|
||||
a = lookup[step + radius].uint32
|
||||
values += sample * a
|
||||
|
||||
blurX.setRgbaUnsafe(x, y, values.rgba())
|
||||
|
||||
# Blur in the Y direction.
|
||||
for y in 0 ..< image.height:
|
||||
for x in 0 ..< image.width:
|
||||
var values: array[4, uint32]
|
||||
for yb in -radius .. radius:
|
||||
let
|
||||
sample = blurX[x, y + yb]
|
||||
a = lookup[yb + radius].uint32
|
||||
values += sample * a
|
||||
if image.inside(x, y - radius) and image.inside(x, y + radius):
|
||||
for step in -radius .. radius:
|
||||
let
|
||||
sample = blurX.getRgbaUnsafe(x, y + step)
|
||||
a = lookup[step + radius].uint32
|
||||
values += sample * a
|
||||
else:
|
||||
for step in -radius .. radius:
|
||||
let
|
||||
sample = blurX[x, y + step]
|
||||
a = lookup[step + radius].uint32
|
||||
values += sample * a
|
||||
|
||||
image.setRgbaUnsafe(x, y, values.rgba())
|
||||
|
||||
proc newMask*(image: Image): Mask =
|
||||
|
|
|
@ -154,7 +154,7 @@ proc ceil*(mask: Mask) =
|
|||
if mask.data[j] != 0:
|
||||
mask.data[j] = 255
|
||||
|
||||
proc blur*(mask: Mask, radius: float32, offBounds: uint32 = 0) =
|
||||
proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) =
|
||||
## Applies Gaussian blur to the image given a radius.
|
||||
let radius = round(radius).int
|
||||
if radius == 0:
|
||||
|
@ -167,28 +167,39 @@ proc blur*(mask: Mask, radius: float32, offBounds: uint32 = 0) =
|
|||
for y in 0 ..< mask.height:
|
||||
for x in 0 ..< mask.width:
|
||||
var value: uint32
|
||||
for xb in -radius .. radius:
|
||||
var sample: uint32
|
||||
if mask.inside(x + xb, y):
|
||||
sample = mask.getValueUnsafe(x + xb, y)
|
||||
else:
|
||||
sample = offBounds
|
||||
let a = lookup[xb + radius].uint32
|
||||
value += sample * a
|
||||
if mask.inside(x - radius, y) and mask.inside(x + radius, y):
|
||||
for step in -radius .. radius:
|
||||
let sample = mask.getValueUnsafe(x + step, y)
|
||||
value += sample * lookup[step + radius].uint32
|
||||
else:
|
||||
for step in -radius .. radius:
|
||||
var sample: uint32
|
||||
if mask.inside(x + step, y):
|
||||
sample = mask.getValueUnsafe(x + step, y)
|
||||
else:
|
||||
sample = outOfBounds
|
||||
value += sample * lookup[step + radius].uint32
|
||||
|
||||
blurX.setValueUnsafe(x, y, (value div 1024 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 yb in -radius .. radius:
|
||||
var sample: uint32
|
||||
if blurX.inside(x, y + yb):
|
||||
sample = blurX.getValueUnsafe(x, y + yb)
|
||||
else:
|
||||
sample = offBounds
|
||||
let a = lookup[yb + radius].uint32
|
||||
value += sample * a
|
||||
if mask.inside(x, y - radius) and mask.inside(x, y + radius):
|
||||
for step in -radius .. radius:
|
||||
let sample = blurX.getValueUnsafe(x, y + step)
|
||||
value += sample * lookup[step + radius].uint32
|
||||
else:
|
||||
for step in -radius .. radius:
|
||||
var sample: uint32
|
||||
if blurX.inside(x, y + step):
|
||||
sample = blurX.getValueUnsafe(x, y + step)
|
||||
else:
|
||||
sample = outOfBounds
|
||||
let a = lookup[step + radius].uint32
|
||||
value += sample * a
|
||||
|
||||
mask.setValueUnsafe(x, y, (value div 1024 div 255).uint8)
|
||||
|
||||
when defined(release):
|
||||
|
|
Loading…
Reference in a new issue