Merge pull request #310 from guzba/master
3.0.1, minifyBy2 fix for non-even src dimens
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
BIN
tests/images/diffs/minify_odd.png
Normal file
After Width: | Height: | Size: 326 B |
Before Width: | Height: | Size: 353 B After Width: | Height: | Size: 411 B |
Before Width: | Height: | Size: 408 B After Width: | Height: | Size: 479 B |
BIN
tests/images/masters/minify_odd.png
Normal file
After Width: | Height: | Size: 381 B |
Before Width: | Height: | Size: 194 B After Width: | Height: | Size: 211 B |
Before Width: | Height: | Size: 161 B After Width: | Height: | Size: 179 B |
BIN
tests/images/rendered/minify_odd.png
Normal file
After Width: | Height: | Size: 378 B |
|
@ -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")
|
||||
|
|