simpler + out of bounds color for image blur
This commit is contained in:
parent
851c15f943
commit
004182a122
6 changed files with 64 additions and 50 deletions
|
@ -317,7 +317,7 @@ proc invert*(target: Image | Mask) =
|
||||||
for j in i ..< target.data.len:
|
for j in i ..< target.data.len:
|
||||||
target.data[j] = (255 - target.data[j]).uint8
|
target.data[j] = (255 - target.data[j]).uint8
|
||||||
|
|
||||||
proc blur*(image: Image, radius: float32) =
|
proc blur*(image: Image, radius: float32, outOfBounds = ColorRGBX()) =
|
||||||
## Applies Gaussian blur to the image given a radius.
|
## Applies Gaussian blur to the image given a radius.
|
||||||
let radius = round(radius).int
|
let radius = round(radius).int
|
||||||
if radius == 0:
|
if radius == 0:
|
||||||
|
@ -354,18 +354,23 @@ proc blur*(image: Image, radius: float32) =
|
||||||
for y in 0 ..< image.height:
|
for y in 0 ..< image.height:
|
||||||
for x in 0 ..< image.width:
|
for x in 0 ..< image.width:
|
||||||
var values: array[4, uint32]
|
var values: array[4, uint32]
|
||||||
if image.inside(x - radius, y) and image.inside(x + radius, y):
|
for xx in x - radius ..< min(x + radius, 0):
|
||||||
for step in -radius .. radius:
|
let
|
||||||
let
|
sample = outOfBounds
|
||||||
sample = image.getRgbaUnsafe(x + step, y)
|
a = lookup[xx - x + radius].uint32
|
||||||
a = lookup[step + radius].uint32
|
values += sample * a
|
||||||
values += sample * a
|
|
||||||
else:
|
for xx in max(x - radius, 0) ..< min(x + radius, image.width):
|
||||||
for step in -radius .. radius:
|
let
|
||||||
let
|
sample = image.getRgbaUnsafe(xx, y)
|
||||||
sample = image[x + step, y]
|
a = lookup[xx - x + radius].uint32
|
||||||
a = lookup[step + radius].uint32
|
values += sample * a
|
||||||
values += sample * a
|
|
||||||
|
for xx in max(x - radius, image.width) ..< x + radius:
|
||||||
|
let
|
||||||
|
sample = outOfBounds
|
||||||
|
a = lookup[xx - x + radius].uint32
|
||||||
|
values += sample * a
|
||||||
|
|
||||||
blurX.setRgbaUnsafe(x, y, values.rgbx())
|
blurX.setRgbaUnsafe(x, y, values.rgbx())
|
||||||
|
|
||||||
|
@ -373,18 +378,23 @@ proc blur*(image: Image, radius: float32) =
|
||||||
for y in 0 ..< image.height:
|
for y in 0 ..< image.height:
|
||||||
for x in 0 ..< image.width:
|
for x in 0 ..< image.width:
|
||||||
var values: array[4, uint32]
|
var values: array[4, uint32]
|
||||||
if image.inside(x, y - radius) and image.inside(x, y + radius):
|
for yy in y - radius ..< min(y + radius, 0):
|
||||||
for step in -radius .. radius:
|
let
|
||||||
let
|
sample = outOfBounds
|
||||||
sample = blurX.getRgbaUnsafe(x, y + step)
|
a = lookup[yy - y + radius].uint32
|
||||||
a = lookup[step + radius].uint32
|
values += sample * a
|
||||||
values += sample * a
|
|
||||||
else:
|
for yy in max(y - radius, 0) ..< min(y + radius, image.height):
|
||||||
for step in -radius .. radius:
|
let
|
||||||
let
|
sample = blurX.getRgbaUnsafe(x, yy)
|
||||||
sample = blurX[x, y + step]
|
a = lookup[yy - y + radius].uint32
|
||||||
a = lookup[step + radius].uint32
|
values += sample * a
|
||||||
values += sample * a
|
|
||||||
|
for yy in max(y - radius, image.height) ..< y + radius:
|
||||||
|
let
|
||||||
|
sample = outOfBounds
|
||||||
|
a = lookup[yy - y + radius].uint32
|
||||||
|
values += sample * a
|
||||||
|
|
||||||
image.setRgbaUnsafe(x, y, values.rgbx())
|
image.setRgbaUnsafe(x, y, values.rgbx())
|
||||||
|
|
||||||
|
|
|
@ -167,18 +167,17 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) =
|
||||||
for y in 0 ..< mask.height:
|
for y in 0 ..< mask.height:
|
||||||
for x in 0 ..< mask.width:
|
for x in 0 ..< mask.width:
|
||||||
var value: uint32
|
var value: uint32
|
||||||
if mask.inside(x - radius, y) and mask.inside(x + radius, y):
|
for xx in x - radius ..< min(x + radius, 0):
|
||||||
for step in -radius .. radius:
|
let sample = outOfBounds
|
||||||
let sample = mask.getValueUnsafe(x + step, y)
|
value += sample * lookup[xx - x + radius].uint32
|
||||||
value += sample * lookup[step + radius].uint32
|
|
||||||
else:
|
for xx in max(x - radius, 0) ..< min(x + radius, mask.width):
|
||||||
for step in -radius .. radius:
|
let sample = mask.getValueUnsafe(xx, y)
|
||||||
var sample: uint32
|
value += sample * lookup[xx - x + radius].uint32
|
||||||
if mask.inside(x + step, y):
|
|
||||||
sample = mask.getValueUnsafe(x + step, y)
|
for xx in max(x - radius, mask.width) ..< x + radius:
|
||||||
else:
|
let sample = outOfBounds
|
||||||
sample = outOfBounds
|
value += sample * lookup[xx - x + radius].uint32
|
||||||
value += sample * lookup[step + radius].uint32
|
|
||||||
|
|
||||||
blurX.setValueUnsafe(x, y, (value div 1024 div 255).uint8)
|
blurX.setValueUnsafe(x, y, (value div 1024 div 255).uint8)
|
||||||
|
|
||||||
|
@ -186,19 +185,17 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) =
|
||||||
for y in 0 ..< mask.height:
|
for y in 0 ..< mask.height:
|
||||||
for x in 0 ..< mask.width:
|
for x in 0 ..< mask.width:
|
||||||
var value: uint32
|
var value: uint32
|
||||||
if mask.inside(x, y - radius) and mask.inside(x, y + radius):
|
for yy in y - radius ..< min(y + radius, 0):
|
||||||
for step in -radius .. radius:
|
let sample = outOfBounds
|
||||||
let sample = blurX.getValueUnsafe(x, y + step)
|
value += sample * lookup[yy - y + radius].uint32
|
||||||
value += sample * lookup[step + radius].uint32
|
|
||||||
else:
|
for yy in max(y - radius, 0) ..< min(y + radius, mask.height):
|
||||||
for step in -radius .. radius:
|
let sample = blurX.getValueUnsafe(x, yy)
|
||||||
var sample: uint32
|
value += sample * lookup[yy - y + radius].uint32
|
||||||
if blurX.inside(x, y + step):
|
|
||||||
sample = blurX.getValueUnsafe(x, y + step)
|
for yy in max(y - radius, mask.height) ..< y + radius:
|
||||||
else:
|
let sample = outOfBounds
|
||||||
sample = outOfBounds
|
value += sample * lookup[yy - y + radius].uint32
|
||||||
let a = lookup[step + radius].uint32
|
|
||||||
value += sample * a
|
|
||||||
|
|
||||||
mask.setValueUnsafe(x, y, (value div 1024 div 255).uint8)
|
mask.setValueUnsafe(x, y, (value div 1024 div 255).uint8)
|
||||||
|
|
||||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.7 KiB |
BIN
tests/images/imageblur20oob.png
Normal file
BIN
tests/images/imageblur20oob.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4 KiB |
Binary file not shown.
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.2 KiB |
|
@ -111,3 +111,10 @@ block:
|
||||||
image.fillRect(rect(25, 25, 50, 50), rgba(255, 255, 255, 255))
|
image.fillRect(rect(25, 25, 50, 50), rgba(255, 255, 255, 255))
|
||||||
image.blur(20)
|
image.blur(20)
|
||||||
image.writeFile("tests/images/imageblur20.png")
|
image.writeFile("tests/images/imageblur20.png")
|
||||||
|
|
||||||
|
block:
|
||||||
|
let image = newImage(100, 100)
|
||||||
|
image.fill(rgba(0, 0, 0, 255))
|
||||||
|
image.fillRect(rect(25, 25, 50, 50), rgba(255, 255, 255, 255))
|
||||||
|
image.blur(20, rgba(0, 0, 0, 255))
|
||||||
|
image.writeFile("tests/images/imageblur20oob.png")
|
||||||
|
|
Loading…
Reference in a new issue