commit
df438b7085
3 changed files with 61 additions and 0 deletions
|
@ -129,6 +129,12 @@ proc subImage*(image: Image, x, y, w, h: int): Image {.raises: [PixieError].} =
|
||||||
w * 4
|
w * 4
|
||||||
)
|
)
|
||||||
|
|
||||||
|
proc subImage*(image: Image, rect: Rect): Image {.raises: [PixieError].} =
|
||||||
|
## Gets a sub image from this image via rectangle.
|
||||||
|
## Rectangle is snapped/expanded to whole pixels first.
|
||||||
|
let r = rect.snapToPixels()
|
||||||
|
image.subImage(r.x.int, r.y.int, r.w.int, r.h.int)
|
||||||
|
|
||||||
proc diff*(master, image: Image): (float32, Image) {.raises: [PixieError].} =
|
proc diff*(master, image: Image): (float32, Image) {.raises: [PixieError].} =
|
||||||
## Compares the parameters and returns a score and image of the difference.
|
## Compares the parameters and returns a score and image of the difference.
|
||||||
let
|
let
|
||||||
|
@ -751,5 +757,33 @@ proc superImage*(image: Image, x, y, w, h: int): Image {.raises: [PixieError].}
|
||||||
result = newImage(w, h)
|
result = newImage(w, h)
|
||||||
result.draw(image, translate(vec2(-x.float32, -y.float32)), OverwriteBlend)
|
result.draw(image, translate(vec2(-x.float32, -y.float32)), OverwriteBlend)
|
||||||
|
|
||||||
|
proc opaqueBounds*(image: Image): Rect =
|
||||||
|
## Returns the bounds of opaque pixels.
|
||||||
|
## Some images have transparency around them, use this to find just the
|
||||||
|
## visible part of the image and then use subImage to cut it out.
|
||||||
|
## Returns zero rect if whole image is transparent.
|
||||||
|
## Returns just the size of the image if no edge is transparent.
|
||||||
|
var
|
||||||
|
xMin = image.width
|
||||||
|
xMax = 0
|
||||||
|
yMin = image.height
|
||||||
|
yMax = 0
|
||||||
|
# Find the trim coordinates.
|
||||||
|
for y in 0 ..< image.height:
|
||||||
|
for x in 0 ..< image.width:
|
||||||
|
if image.unsafe[x, y].a != 0:
|
||||||
|
xMin = min(xMin, x)
|
||||||
|
xMax = max(xMax, x + 1)
|
||||||
|
yMin = min(yMin, y)
|
||||||
|
yMax = max(yMax, y + 1)
|
||||||
|
if xMax <= xMin or yMax <= yMin:
|
||||||
|
return rect(0, 0, 0, 0)
|
||||||
|
rect(
|
||||||
|
xMin.float32,
|
||||||
|
yMin.float32,
|
||||||
|
(xMax - xMin).float32,
|
||||||
|
(yMax - yMin).float32
|
||||||
|
)
|
||||||
|
|
||||||
when defined(release):
|
when defined(release):
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
BIN
tests/images/opaqueBounds.png
Normal file
BIN
tests/images/opaqueBounds.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 372 B |
|
@ -231,3 +231,30 @@ block:
|
||||||
let image = newImage(100, 100)
|
let image = newImage(100, 100)
|
||||||
image.fill("white")
|
image.fill("white")
|
||||||
doAssert image[10, 10] == rgba(255, 255, 255, 255)
|
doAssert image[10, 10] == rgba(255, 255, 255, 255)
|
||||||
|
|
||||||
|
block:
|
||||||
|
# opaqueBounds of fully transparent image.
|
||||||
|
let image = newImage(100, 100)
|
||||||
|
doAssert image.opaqueBounds() == rect(0, 0, 0, 0)
|
||||||
|
|
||||||
|
block:
|
||||||
|
# opaqueBounds of fully opaque image.
|
||||||
|
let image = newImage(100, 100)
|
||||||
|
image.fill(rgbx(255, 255, 255, 255))
|
||||||
|
doAssert image.opaqueBounds() == rect(0.0, 0.0, 100.0, 100.0)
|
||||||
|
|
||||||
|
block:
|
||||||
|
let image = newImage(160, 160)
|
||||||
|
image.fillPath(
|
||||||
|
"""
|
||||||
|
M 20 20
|
||||||
|
L 140 20
|
||||||
|
L 80 140
|
||||||
|
z
|
||||||
|
""",
|
||||||
|
parseHtmlColor("#FC427B").rgba,
|
||||||
|
scale(vec2(0.3, 0.3))
|
||||||
|
)
|
||||||
|
let rect = image.opaqueBounds()
|
||||||
|
let trimmedImage = image.subImage(rect)
|
||||||
|
trimmedImage.xray("tests/images/opaqueBounds.png")
|
||||||
|
|
Loading…
Reference in a new issue