Merge pull request #143 from guzba/master
simpler + out of bounds color for image blur
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 90 KiB |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 9.2 KiB |
|
@ -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"
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.7 KiB |
BIN
tests/images/imageblur20oob.png
Normal file
After Width: | Height: | Size: 4 KiB |
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.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")
|
||||
|
|