Merge pull request #143 from guzba/master

simpler + out of bounds color for image blur
This commit is contained in:
treeform 2021-02-26 17:25:56 -08:00 committed by GitHub
commit 36b10a62d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 60 additions and 71 deletions

View file

@ -538,7 +538,7 @@ Strokes a polygon.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

View file

@ -283,7 +283,7 @@ Is there a blend masking function with SIMD support?
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:33 UTC</small>
</div>
</div>
</div>

View file

@ -196,7 +196,7 @@ Linearly interpolate between a and b using t.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:33 UTC</small>
</div>
</div>
</div>

View file

@ -182,7 +182,7 @@ Encodes an image into the BMP file format.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:33 UTC</small>
</div>
</div>
</div>

View file

@ -182,7 +182,7 @@ Encodes Image into a JPEG data string.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

View file

@ -201,7 +201,7 @@ Encodes the mask data into the PNG file format.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

View file

@ -171,7 +171,7 @@ Render SVG file and return the image. Defaults to the SVG's view box size.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

View file

@ -231,7 +231,7 @@ function main() {
</ul>
<ul class="simple nested-toc-section">blur
<li><a class="reference" href="#blur%2CImage%2Cfloat32"
title="blur(image: Image; radius: float32)">blur,<wbr>Image,<wbr>float32</a></li>
title="blur(image: Image; radius: float32; outOfBounds = ColorRGBX())">blur,<wbr>Image,<wbr>float32</a></li>
</ul>
<ul class="simple nested-toc-section">dataIndex
@ -451,7 +451,8 @@ Inverts all of the colors and alpha.
</dd>
<a id="blur,Image,float32"></a>
<dt><pre><span class="Keyword">proc</span> <a href="#blur%2CImage%2Cfloat32"><span class="Identifier">blur</span></a><span class="Other">(</span><span class="Identifier">image</span><span class="Other">:</span> <a href="images.html#Image"><span class="Identifier">Image</span></a><span class="Other">;</span> <span class="Identifier">radius</span><span class="Other">:</span> <span class="Identifier">float32</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma"><span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">PixieError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
<dt><pre><span class="Keyword">proc</span> <a href="#blur%2CImage%2Cfloat32"><span class="Identifier">blur</span></a><span class="Other">(</span><span class="Identifier">image</span><span class="Other">:</span> <a href="images.html#Image"><span class="Identifier">Image</span></a><span class="Other">;</span> <span class="Identifier">radius</span><span class="Other">:</span> <span class="Identifier">float32</span><span class="Other">;</span> <span class="Identifier">outOfBounds</span> <span class="Other">=</span> <span class="Identifier">ColorRGBX</span><span class="Other">(</span><span class="Other">)</span><span class="Other">)</span> <span><span class="Other">{</span><span class="Other pragmadots">...</span><span class="Other">}</span></span><span class="pragmawrap"><span class="Other">{.</span><span class="pragma">
<span class="Identifier">raises</span><span class="Other">:</span> <span class="Other">[</span><span class="Identifier">PixieError</span><span class="Other">]</span><span class="Other">,</span> <span class="Identifier">tags</span><span class="Other">:</span> <span class="Other">[</span><span class="Other">]</span></span><span class="Other">.}</span></span></pre></dt>
<dd>
Applies Gaussian blur to the image given a radius.
@ -577,7 +578,7 @@ Create a shadow of the image with the offset, spread and blur.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:33 UTC</small>
</div>
</div>
</div>

View file

@ -19,7 +19,7 @@ minifyBy2 pixie/images.html#minifyBy2,Image,int images: minifyBy2(image: Image;
magnifyBy2 pixie/images.html#magnifyBy2,Image,int images: magnifyBy2(image: Image; power = 1): Image
applyOpacity pixie/images.html#applyOpacity,,float32 images: applyOpacity(target: Image | Mask; opacity: float32)
invert pixie/images.html#invert images: invert(target: Image | Mask)
blur pixie/images.html#blur,Image,float32 images: blur(image: Image; radius: float32)
blur pixie/images.html#blur,Image,float32 images: blur(image: Image; radius: float32; outOfBounds = ColorRGBX())
newMask pixie/images.html#newMask,Image images: newMask(image: Image): Mask
getRgbaSmooth pixie/images.html#getRgbaSmooth,Image,float32,float32 images: getRgbaSmooth(image: Image; x, y: float32; wrapped = false): ColorRGBX
draw pixie/images.html#draw,Image,Image,Mat3 images: draw(a, b: Image; mat: Mat3; blendMode = bmNormal)

View file

@ -178,7 +178,7 @@ Unpack the first 32 bits into 4 rgba(0, 0, 0, value)
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:33 UTC</small>
</div>
</div>
</div>

View file

@ -367,7 +367,7 @@ Applies Gaussian blur to the image given a radius.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:33 UTC</small>
</div>
</div>
</div>

View file

@ -243,7 +243,7 @@ Angular gradient.
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

View file

@ -662,7 +662,7 @@ Return elements in pairs: (1st, 2nd), (2nd, 3rd) ... (n - 1, last).
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

View file

@ -134,7 +134,7 @@ function main() {
</ul></dd>
<dt><a name="blur" href="#blur"><span>blur:</span></a></dt><dd><ul class="simple">
<li><a class="reference external"
data-doc-search-tag="images: blur(image: Image; radius: float32)" href="pixie/images.html#blur%2CImage%2Cfloat32">images: blur(image: Image; radius: float32)</a></li>
data-doc-search-tag="images: blur(image: Image; radius: float32; outOfBounds = ColorRGBX())" href="pixie/images.html#blur%2CImage%2Cfloat32">images: blur(image: Image; radius: float32; outOfBounds = ColorRGBX())</a></li>
<li><a class="reference external"
data-doc-search-tag="masks: blur(mask: Mask; radius: float32; outOfBounds: uint8 = 0)" href="pixie/masks.html#blur%2CMask%2Cfloat32%2Cuint8">masks: blur(mask: Mask; radius: float32; outOfBounds: uint8 = 0)</a></li>
</ul></dd>
@ -921,7 +921,7 @@ function main() {
<div class="twelve-columns footer">
<span class="nim-sprite"></span>
<br/>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 00:46:16 UTC</small>
<small style="color: var(--hint);">Made with Nim. Generated: 2021-02-27 01:24:34 UTC</small>
</div>
</div>
</div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.3 KiB

After

Width:  |  Height:  |  Size: 9.2 KiB

View file

@ -1,4 +1,4 @@
version = "1.0.1"
version = "1.0.2"
author = "Andre von Houck and Ryan Oldenburg"
description = "Full-featured 2d graphics library for Nim."
license = "MIT"

View file

@ -317,7 +317,7 @@ proc invert*(target: Image | Mask) =
for j in i ..< target.data.len:
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.
let radius = round(radius).int
if radius == 0:
@ -325,9 +325,7 @@ proc blur*(image: Image, radius: float32) =
let lookup = gaussianLookup(radius)
# TODO support offBounds for images.
template `*`(sample: ColorRGBX, a: uint32): array[4, uint32] =
proc `*`(sample: ColorRGBX, a: uint32): array[4, uint32] {.inline.} =
[
sample.r * a,
sample.g * a,
@ -354,18 +352,14 @@ proc blur*(image: Image, radius: float32) =
for y in 0 ..< image.height:
for x in 0 ..< image.width:
var values: array[4, uint32]
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
for xx in x - radius ..< min(x + radius, 0):
values += outOfBounds * lookup[xx - x + radius]
for xx in max(x - radius, 0) ..< min(x + radius, image.width):
values += image.getRgbaUnsafe(xx, y) * lookup[xx - x + radius]
for xx in max(x - radius, image.width) ..< x + radius:
values += outOfBounds * lookup[xx - x + radius]
blurX.setRgbaUnsafe(x, y, values.rgbx())
@ -373,18 +367,14 @@ proc blur*(image: Image, radius: float32) =
for y in 0 ..< image.height:
for x in 0 ..< image.width:
var values: array[4, uint32]
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
for yy in y - radius ..< min(y + radius, 0):
values += outOfBounds * lookup[yy - y + radius]
for yy in max(y - radius, 0) ..< min(y + radius, image.height):
values += blurX.getRgbaUnsafe(x, yy) * lookup[yy - y + radius]
for yy in max(y - radius, image.height) ..< y + radius:
values += outOfBounds * lookup[yy - y + radius]
image.setRgbaUnsafe(x, y, values.rgbx())

View file

@ -167,18 +167,14 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) =
for y in 0 ..< mask.height:
for x in 0 ..< mask.width:
var value: uint32
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
for xx in x - radius ..< min(x + radius, 0):
value += outOfBounds * lookup[xx - x + radius]
for xx in max(x - radius, 0) ..< min(x + radius, mask.width):
value += mask.getValueUnsafe(xx, y) * lookup[xx - x + radius]
for xx in max(x - radius, mask.width) ..< x + radius:
value += outOfBounds * lookup[xx - x + radius]
blurX.setValueUnsafe(x, y, (value div 1024 div 255).uint8)
@ -186,19 +182,14 @@ proc blur*(mask: Mask, radius: float32, outOfBounds: uint8 = 0) =
for y in 0 ..< mask.height:
for x in 0 ..< mask.width:
var value: uint32
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
for yy in y - radius ..< min(y + radius, 0):
value += outOfBounds * lookup[yy - y + radius]
for yy in max(y - radius, 0) ..< min(y + radius, mask.height):
value += blurX.getValueUnsafe(x, yy) * lookup[yy - y + radius]
for yy in max(y - radius, mask.height) ..< y + radius:
value += outOfBounds * lookup[yy - y + radius]
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

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

View file

@ -111,3 +111,10 @@ block:
image.fillRect(rect(25, 25, 50, 50), rgba(255, 255, 255, 255))
image.blur(20)
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")