Merge pull request #310 from guzba/master

3.0.1, minifyBy2 fix for non-even src dimens
This commit is contained in:
treeform 2021-10-19 17:21:21 -07:00 committed by GitHub
commit f7ca3fc480
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 60 additions and 15 deletions

View file

@ -1,4 +1,4 @@
version = "3.0.0"
version = "3.0.1"
author = "Andre von Houck and Ryan Oldenburg"
description = "Full-featured 2d graphics library for Nim."
license = "MIT"
@ -6,7 +6,7 @@ license = "MIT"
srcDir = "src"
requires "nim >= 1.4.0"
requires "vmath >= 1.0.11"
requires "vmath >= 1.1.0"
requires "chroma >= 0.2.5"
requires "zippy >= 0.6.2"
requires "flatty >= 0.2.2"

View file

@ -256,14 +256,24 @@ proc minifyBy2*(image: Image, power = 1): Image {.raises: [PixieError].} =
var src = image
for _ in 1 .. power:
result = newImage(src.width div 2, src.height div 2)
for y in 0 ..< result.height:
# When minifying an image of odd size, round the result image size up
# so a 99 x 99 src image returns a 50 x 50 image.
let
srcWidthIsOdd = (src.width mod 2) != 0
srcHeightIsOdd = (src.height mod 2) != 0
resultEvenWidth = src.width div 2
resultEvenHeight = src.height div 2
result = newImage(
if srcWidthIsOdd: resultEvenWidth + 1 else: resultEvenWidth,
if srcHeightIsOdd: resultEvenHeight + 1 else: resultEvenHeight
)
for y in 0 ..< resultEvenHeight:
var x: int
when defined(amd64) and not defined(pixieNoSimd):
let
oddMask = mm_set1_epi16(cast[int16](0xff00))
first32 = cast[M128i]([uint32.high, 0, 0, 0])
for _ in countup(0, result.width - 4, 2):
for _ in countup(0, resultEvenWidth - 4, 2):
let
top = mm_loadu_si128(src.data[src.dataIndex(x * 2, y * 2 + 0)].addr)
btm = mm_loadu_si128(src.data[src.dataIndex(x * 2, y * 2 + 1)].addr)
@ -303,7 +313,7 @@ proc minifyBy2*(image: Image, power = 1): Image {.raises: [PixieError].} =
mm_storeu_si128(result.data[result.dataIndex(x, y)].addr, zeroTwo)
x += 2
for x in x ..< result.width:
for x in x ..< resultEvenWidth:
let
a = src.getRgbaUnsafe(x * 2 + 0, y * 2 + 0)
b = src.getRgbaUnsafe(x * 2 + 1, y * 2 + 0)
@ -318,6 +328,32 @@ proc minifyBy2*(image: Image, power = 1): Image {.raises: [PixieError].} =
result.setRgbaUnsafe(x, y, rgba)
if srcWidthIsOdd:
let rgbx = mix(
src.getRgbaUnsafe(src.width - 1, y * 2 + 0),
src.getRgbaUnsafe(src.width - 1, y * 2 + 1),
0.5
) * 0.5
result.setRgbaUnsafe(result.width - 1, y, rgbx)
if srcHeightIsOdd:
let y = result.height - 1
for x in 0 ..< resultEvenWidth:
let rgbx = mix(
src.getRgbaUnsafe(x * 2 + 0, y),
src.getRgbaUnsafe(x * 2 + 1, y),
0.5
) * 0.5
result.setRgbaUnsafe(x, y, rgbx)
if srcWidthIsOdd:
result.setRgbaUnsafe(
result.width - 1,
result.height - 1,
src.getRgbaUnsafe(src.width - 1, src.height - 1) * 0.25
)
# Set src as this result for if we do another power
src = result

View file

@ -22,7 +22,7 @@ proc gaussianKernel*(radius: int): seq[uint16] {.raises: [].} =
for i, f in floats:
result[i] = round(f * 255 * 256).uint16
proc applyOpacity*(color: ColorRGBX, opacity: float32): ColorRGBX {.raises: [].} =
proc `*`*(color: ColorRGBX, opacity: float32): ColorRGBX {.raises: [].} =
if opacity == 0:
rgbx(0, 0, 0, 0)
else:

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 353 B

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 408 B

After

Width:  |  Height:  |  Size: 479 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 194 B

After

Width:  |  Height:  |  Size: 211 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 179 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

View file

@ -1,5 +1,13 @@
import pixie, strformat
proc doDiff(rendered: Image, name: string) =
rendered.writeFile(&"tests/images/rendered/{name}.png")
let
master = readImage(&"tests/images/masters/{name}.png")
(diffScore, diffImage) = diff(master, rendered)
echo &"{name} score: {diffScore}"
diffImage.writeFile(&"tests/images/diffs/{name}.png")
block:
let
a = newImage(1000, 1000)
@ -128,14 +136,6 @@ block:
a.draw(b, translate(vec2(250, 250)) * scale(vec2(0.5, 0.5)))
a.writeFile("tests/images/scaleHalf.png")
proc doDiff(rendered: Image, name: string) =
rendered.writeFile(&"tests/images/rendered/{name}.png")
let
master = readImage(&"tests/images/masters/{name}.png")
(diffScore, diffImage) = diff(master, rendered)
echo &"{name} score: {diffScore}"
diffImage.writeFile(&"tests/images/diffs/{name}.png")
block:
let
a = newImage(100, 100)
@ -249,3 +249,12 @@ block:
a.draw(b, m * translate(vec2(-40,-40)))
a.draw(b, m * translate(vec2(0,-40)))
doDiff(a, "smooth12")
block:
let
a = newImage(100, 100)
b = newImage(99, 99)
a.fill(rgba(255, 255, 255, 255))
b.fill(rgba(0, 0, 0, 255))
a.draw(b, scale(vec2(0.5, 0.5)))
doDiff(a, "minify_odd")