Merge pull request #4 from guzba/master

read, encode, decode, write
This commit is contained in:
treeform 2020-11-20 20:45:09 -08:00 committed by GitHub
commit 2ee05e25ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 21 deletions

View file

@ -1,8 +1,14 @@
## Public interface to you library.
import pixie/images, pixie/masks, pixie/paths, pixie/common
import pixie/images, pixie/masks, pixie/paths, pixie/common,
pixie/fileformats/bmp, pixie/fileformats/png, flatty/binny
export images, masks, paths, PixieError
type
FileFormat* = enum
ffPng, ffBmp
proc toMask*(image: Image): Mask =
## Converts an Image to a Mask.
result = newMask(image.width, image.height)
@ -14,3 +20,29 @@ proc toImage*(mask: Mask): Image =
result = newImage(mask.width, mask.height)
for i in 0 ..< mask.data.len:
result.data[i].a = mask.data[i]
proc decodeImage(data: string | seq[uint8]): Image =
## Loads an image from a memory.
if data.len > 8 and cast[array[8, uint8]](data.readUint64(0)) == pngSignature:
return decodePng(data)
if data.len > 2 and data.readStr(0, 2) == "BM":
return decodeBmp(data)
raise newException(PixieError, "Unsupported image file format")
proc readImage*(filePath: string): Image =
## Loads an image from a file.
decodeImage(readFile(filePath))
proc encodeImage(image: Image, fileFormat: FileFormat): string =
## Encodes an image into a memory.
case fileFormat:
of ffPng:
image.encodePng()
of ffBmp:
image.encodeBmp()
proc writeFile*(image: Image, filePath: string, fileFormat: FileFormat) =
## Writes an image to a file.
writeFile(filePath, image.encodeImage(fileFormat))

View file

@ -1,4 +1,4 @@
import ../images, flatty/binny, chroma, pixie/common
import flatty/binny, chroma, pixie/common, pixie/images
# See: https://en.wikipedia.org/wiki/BMP_file_format
@ -6,7 +6,7 @@ proc decodeBmp*(data: string): Image =
## Decodes bitmap data into an Image.
# BMP Header
if data[0..1] != "BM":
if data[0 .. 1] != "BM":
raise newException(PixieError, "Invalid BMP data")
let
@ -46,6 +46,9 @@ proc decodeBmp*(data: string): Image =
offset += 3
result[x, result.height - y - 1] = rgba
proc decodeBmp*(data: seq[uint8]): Image {.inline.} =
decodeBmp(cast[string](data))
proc encodeBmp*(image: Image): string =
## Encodes an image into the BMP file format.

View file

@ -1,7 +1,10 @@
import chroma, pixie/images, pixie/common, math, zippy, zippy/crc, flatty/binny
import chroma, pixie/common, math, zippy, zippy/crc, flatty/binny, pixie/images
# See http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html
const
pngSignature* = [137.uint8, 80, 78, 71, 13, 10, 26, 10]
type
ChunkCounts = object
PLTE, IDAT: uint8
@ -286,7 +289,7 @@ proc decodePng*(data: seq[uint8]): Image =
# PNG file signature
let signature = cast[array[8, uint8]](data.readUint64(0))
if signature != [137.uint8, 80, 78, 71, 13, 10, 26, 10]:
if signature != pngSignature:
failInvalid()
var
@ -371,6 +374,9 @@ proc decodePng*(data: seq[uint8]): Image =
result.height = header.height
result.data = parseImageData(header, palette, imageData)
proc decodePng*(data: string): Image {.inline.} =
decodePng(cast[seq[uint8]](data))
proc encodePng*(
width, height, channels: int, data: pointer, len: int
): seq[uint8] =

View file

@ -22,22 +22,6 @@ proc `$`*(image: Image): string =
## Display the image size and channels.
"<Image " & $image.width & "x" & $image.height & ">"
proc decodeImage(data: seq[uint8]): Image =
## Loads an image from a memory.
discard
proc readImage*(filePath: string): Image =
## Loads an image from a file.
discard
proc encodeImage(image: Image): seq[uint8] =
## Encodes an image into a memory.
discard
proc writeFile*(image: Image, filePath: string): Image =
## Writes an image to a file.
discard
proc inside*(image: Image, x, y: int): bool {.inline.} =
## Returns true if (x, y) is inside the image.
x >= 0 and x < image.width and y >= 0 and y < image.height