GithubHelp home page GithubHelp logo

flippy's Introduction

Flippy

⚠️⚠️⚠️ Flippy is not longer developed, all development has moved to pixie. ⚠️⚠️⚠️

Flippy Logo

Flippy is a simple 2d image and drawing library.

Basic usage:

import flippy, vmath, chroma

# load an image
var image = loadImage("tests/lenna.png")
# print it out
echo image
# get a color pixel
echo image.getRgba(100, 100)
# put a color pixel
image.putRgba(10, 10, rgba(255, 0, 0, 255))
# blit a rectangular part from one place to another
blit(image, image, rect(0, 0, 100, 100), rect(100, 100, 100, 100))
# draw a line
image.line(vec2(11, 11), vec2(100, 100), rgba(0, 0, 0, 255))
# minify image by 2 or 1/2 or scale by 50%
image = image.minify(2)
# save the image to a file
image.save("tests/lenna2.png")

Alt text

API: flippy

import flippy

type Image

Main image object that holds the bitmap data.

Image = ref object
 filePath*: string
 width*, height*, channels*, format*: int
 data*: seq[uint8]

type Flippy

Flippy = object
 mipmaps*: seq[Image]

proc $

Display the image path, size and channels.

proc `$`(image: Image): string

proc newImage

Creates a new image with appropriate dimensions.

proc newImage(width, height, channels: int): Image

proc newImage

Creates a new image with a path.

proc newImage(filePath: string; width, height, channels: int): Image

proc loadImage

Loads a png image.

proc loadImage(filePath: string): Image {.raises: [IOError], tags: [ReadIOEffect, RootEffect, WriteIOEffect].}

proc copy

Copies an image creating a new image.

proc copy(image: Image): Image

proc save

Saves a png image.

proc save(image: Image) {.raises: [IOError], tags: [WriteIOEffect, RootEffect].}

proc save

Sets image path and save the image.

proc save(image: Image; filePath: string) {.raises: [IOError], tags: [WriteIOEffect, RootEffect].}

proc inside

Returns true if (x, y) is inside the image.

proc inside(image: Image; x, y: int): bool {.inline.}

proc getRgbaUnsafe

Gets a color from (x, y) coordinates.

  • No bounds checking *

Make sure that x, y are in bounds. Failure in the assumptions will case unsafe memory reads.

proc getRgbaUnsafe(image: Image; x, y: int): ColorRGBA {.inline.}

proc getRgbaUnsafe

Gets a pixel as (x, y) floats.

  • No bounds checking *

Make sure that x, y are in bounds. Failure in the assumptions will case unsafe memory reads.

proc getRgbaUnsafe(image: Image; x, y: float64): ColorRGBA {.inline.}

proc getRgba

Gets a pixel at (x, y) or returns transparent black if outside of bounds. Slower due to bounds checking.

proc getRgba(image: Image; x, y: int): ColorRGBA {.inline.}

proc getRgbaSmooth

Gets a pixel as (x, y) floats.

proc getRgbaSmooth(image: Image; x, y: float64): ColorRGBA {.inline.}

proc putRgbaUnsafe

Puts a ColorRGBA pixel back.

  • No bounds checking *

Make sure that x, y are in bounds. Failure in the assumptions will case unsafe memory writes.

proc putRgbaUnsafe(image: Image; x, y: int; rgba: ColorRGBA) {.inline.}

proc putRgbaUnsafe

Puts a ColorRGBA pixel back as x, y floats (does not do blending).

  • No bounds checking *

Make sure that x, y are in bounds. Failure in the assumptions will case unsafe memory writes.

proc putRgbaUnsafe(image: Image; x, y: float64; rgba: ColorRGBA) {.inline, tags: [].}

proc putRgba

Puts pixel onto the image or safely ignored if pixel is outside the image. Slower due to bounds checking.

proc putRgba(image: Image; x, y: int; rgba: ColorRGBA) {.inline.}

proc minifyBy2

Scales the image down by an integer scale.

proc minifyBy2(image: Image): Image

proc minify

Scales the image down by an integer scale.

proc minify(image: Image; scale: int): Image

proc magnify

Scales image image up by an integer scale.

proc magnify(image: Image; scale: int): Image

proc blitUnsafe

Blits rectangle from one image to the other image.

  • No bounds checking *

Make sure that src and dest rect are in bounds. Make sure that channels for images are the same. Failure in the assumptions will case unsafe memory writes.

proc blitUnsafe(destImage: Image; srcImage: Image; src, dest: Rect)

proc blit

Blits rectangle from one image to the other image.

proc blit(destImage: Image; srcImage: Image; src, dest: Rect)

proc blit

Blits rectangle from one image to the other image.

proc blit(destImage: Image; srcImage: Image; pos: Vec2)

proc blitWithAlpha

Blits rectangle from one image to the other image.

proc blitWithAlpha(destImage: Image; srcImage: Image; src, dest: Rect)

proc blitWithMask

Blits rectangle from one image to the other image with masking color.

proc blitWithMask(destImage: Image; srcImage: Image; src, dest: Rect; rgba: ColorRGBA)

proc getSubImage

Gets a sub image of the main image.

proc getSubImage(image: Image; x, y, w, h: int): Image

proc trim

Trims the transparent (alpha=0) border around the image.

proc trim(image: Image): Image

proc flipHorizontal

Flips the image around the Y axis.

proc flipHorizontal(image: Image): Image

proc flipVertical

Flips the image around the X axis.

proc flipVertical(image: Image): Image

proc blit

Blits one image onto another using matrix with alpha blending.

proc blit(destImage, srcImage: Image; mat: Mat4)

proc blitWithAlpha

Blits one image onto another using matrix with alpha blending.

proc blitWithAlpha(destImage: Image; srcImage: Image; mat: Mat4)

proc fill

Fills the image with a solid color.

proc fill(image: Image; rgba: ColorRGBA)

proc line

Draws a line from one at vec to to vec.

proc line(image: Image; at, to: Vec2; rgba: ColorRGBA)

proc fillRect

Draws a filled rectangle.

proc fillRect(image: Image; rect: Rect; rgba: ColorRGBA)

proc strokeRect

Draws a rectangle borders only.

proc strokeRect(image: Image; rect: Rect; rgba: ColorRGBA)

proc fillCircle

Draws a filled circle with antialiased edges.

proc fillCircle(image: Image; pos: Vec2; radius: float; rgba: ColorRGBA)

proc strokeCircle

Draws a border of circle with antialiased edges.

proc strokeCircle(image: Image; pos: Vec2; radius, border: float; rgba: ColorRGBA)

proc fillRoundedRect

Fills image with a rounded rectangle.

proc fillRoundedRect(image: Image; rect: Rect; radius: float; rgba: ColorRGBA)

proc strokeRoundedRect

Fills image with a stroked rounded rectangle.

proc strokeRoundedRect(image: Image; rect: Rect; radius, border: float; rgba: ColorRGBA)

proc ninePatch

Draws a 9-patch

proc ninePatch(image: Image; rect: Rect; radius, border: float; fill, stroke: ColorRGBA)

proc rotate90Degrees

Rotates the image clockwise.

proc rotate90Degrees(image: Image): Image

proc rotateNeg90Degrees

Rotates the image anti-clockwise.

proc rotateNeg90Degrees(image: Image): Image

proc shearX

Shears the image horizontally; resizes to fit.

proc shearX(image: Image; shear: float): Image

proc shearY

Shears the image vertically; resizes to fit.

proc shearY(image: Image; shear: float): Image

proc rotate

Rotates the image by given angle (in degrees) using the 3-shear method (Paeth method)

proc rotate(image: Image; angle: float): Image

proc removeAlpha

Removes alpha channel from the images by: Setting it to 255 everywhere.

proc removeAlpha(image: Image)

proc alphaBleed

PNG saves space by encoding alpha = 0 areas as black however scaling such images lets the black or gray come out. This bleeds the real colors into invisible space.

proc alphaBleed(image: Image)

proc blur

Blurs the image by x and y directions.

proc blur(image: Image; xBlur: int; yBlur: int): Image

proc resize

proc resize(srcImage: Image; width, height: int): Image

proc outlineBorder

Adds n pixel border around alpha parts of the image.

proc outlineBorder(image: Image; borderPx: int): Image

func width

func width(flippy: Flippy): int

func height

func height(flippy: Flippy): int

proc save

Flippy is a special file format that is fast to load and save with mip maps.

proc save(flippy: Flippy; filePath: string) {.raises: [Exception, IOError, OSError, SnappyException], tags: [WriteIOEffect].}

proc pngToFlippy

proc pngToFlippy(pngPath, flippyPath: string) {.raises: [IOError, Exception, OSError, SnappyException], tags: [ReadIOEffect, RootEffect, WriteIOEffect].}

proc loadFlippy

Flippy is a special file format that is fast to load and save with mip maps.

proc loadFlippy(filePath: string): Flippy {.raises: [Exception, IOError, OSError, ValueError, SnappyException], tags: [WriteIOEffect, ReadIOEffect].}

flippy's People

Contributors

benjif avatar dom96 avatar guzba avatar treeform avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

flippy's Issues

Resizing Images using -d:useStl giving strange results

I have a test image:
image
as you can see, it's roughly 10mb big and has a resolution 10315y7049

if i run the following code, it results in that image:

     var image = loadImage(file)
      if image.width > maxWidth or image.height > maxHeight:
        var height = cast[float64](image.height)
        var width = cast[float64](image.width)
        var finalHeight, finalWidth: int
        #echo "Resolution old ", image.height, "x", image.width
        var vh = cast[float64](height / width)
        #echo "VH: ", vh
        if height >= width:
          finalHeight = cast[int](maxHeight)
          finalWidth = cast[int](width / vh)
        else:
          finalWidth = cast[int](maxWidth)
          finalHeight = cast[int](height * vh)
        #echo "Resolution:", image.height, "x", image.width, "-->", finalHeight, "x", finalWidth
        image.height = finalHeight
        image.width = finalWidth  
        image.save(file)

The resulting image has a size of 40MB and looks like this:
image

unable to rotate image?

Hello!

I am trying to do a test rotation on an image.
I am using this code

var test = newImage(50,50,4)
discard test.rotate(2)

but it fails with the following error message:

/Users/teras/Works/Development/Nim/emailform/emailform.nim(7) emailform
/Users/teras/.nimble/pkgs/flippy-0.4.1/flippy.nim(684) rotate
/Users/teras/.nimble/pkgs/flippy-0.4.1/flippy.nim(578) getSubImage
/Users/teras/.nimble/pkgs/flippy-0.4.1/flippy.nim(159) getRgba
/Users/teras/.choosenim/toolchains/nim-1.0.6/lib/system/assertions.nim(27) failedAssertImpl
/Users/teras/.choosenim/toolchains/nim-1.0.6/lib/system/assertions.nim(20) raiseAssert
/Users/teras/.choosenim/toolchains/nim-1.0.6/lib/system/fatal.nim(39) sysFatal
Error: unhandled exception: /Users/teras/.nimble/pkgs/flippy-0.4.1/flippy.nim(159, 10) `y >= 0 and y < image.height`  [AssertionError]

Am I using it wrong?

Flippy is not loading an image

When trying to load an image into flippy i'm getting illegal storage access errors and a signature mismatch error as well
Error seems to originate at line 106 where it is assigning the image width from png.width to result.width

flippy version: 0.4.5
os: OSX

the code to load in an image: var mainImage: Image = loadImage(imagepath)
Full error below

signature mismatch
Traceback (most recent call last)
/Users/__/Projects/Code/imgToGif/src/splitTga.nim(58) splitTga
/Users/__/Projects/Code/imgToGif/src/splitTga.nim(8) splitTgaToPng
/Users/__/.nimble/pkgs/flippy-0.4.5/flippy.nim(106) loadImage
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

Unable to build/install other libraries (e.g. NSU) that depends on flippy

There's an issue when trying to install other libraries such as Senketsu/nsu which depends on flippy. According to the error, it seems the issue lies with flippy.nim having an undeclared identifier "Rect". I also tried the latest version of flippy and it produced the same error.

The error I am getting is
/root/.nimble/pkgs/flippy-0.4.0/flippy.nim(206, 58) Error: undeclared identifier: 'Rect'
Tip: 16 messages have been suppressed, use --verbose to show them.
Error: Build failed for package: nsu
... Execution failed with exit code 1
... Command: /home/user/Desktop/nim-1.4.8/bin/nim c --colors:on --noNimblePath -d:release -d:NimblePkgVersion=0.1.5 --path:/root/.nimble/pkgs/x11-1.1 --path:/root/.nimble/pkgs/winim-3.6.1 --path:/root/.nimble/pkgs/flippy-0.4.0 --path:/root/.nimble/pkgs/vmath-1.0.8 --path:/root/.nimble/pkgs/chroma-0.2.5 --path:/root/.nimble/pkgs/print-1.0.0 --path:/root/.nimble/pkgs/stb_image-2.5 --hints:off -o:/home/user/Desktop/nsu/nsu /home/user/Desktop/nsu/src/nsu.nim

Loops in flippy access memory discontinuously

In procs in src/flippy.nim, most loop change y coordinate in inner loop and change x coordinate in outer loop.
That means these loops access memory discontinuously.
I think inner loop and outer loop in src/flippy.nim should be swapped for continuous memory access and better performance.

I swapped inner loop and outer loop of flippy.blit and measured time.

test.nim:

import flippy, times, vmath, chroma

template measure(body: untyped) =
  let before = epochTime()
  body
  let after = epochTime()

  echo after - before, "sec"
 
#changed inner loop and outer loop of flippy.blit for continuous memory access
proc blit2(destImage: Image, srcImage: Image, pos: Vec2) =
  for y in 0..<int(srcImage.height):
    for x in 0..<int(srcImage.width):
      var rgba = srcImage.getRgba(x, y)
      destImage.putRgbaSafe(int(pos.x) + x, int(pos.y) + y, rgba)

proc main =
  const
    width = 4000
    height = 4000

  var
    src = newImage(width, height, 4)
    dst = newImage(width, height, 4)

  for y in 0..<height:
    for x in 0..<width:
      let v = uint8((x xor y) and 0xff)
      src.putRgba(x, y, ColorRGBA(r: v, g: v, b: v, a: 255))

  measure:
    blit(dst, src, vec2(0.0, 0.0))
    #blit2(dst, src, vec2(0.0, 0.0))

  dst.save("test.png")

main()

I compiled it with following command:

nim c -r -d:danger test.nim

When I measured flippy.blit, time was about 0.42 seconds.
When I measured blit2, time was about 0.083 seconds.

>nim -v
Nim Compiler Version 1.2.6 [Windows: amd64]
Compiled at 2020-07-29
Copyright (c) 2006-2020 by Andreas Rumpf

git hash: bf320ed172f74f60fd274338e82bdc9ce3520dd9
active boot switches: -d:release

Incorrect color after minifying image

var img = newImage(500, 500, 4)

img.fill(rgba(255, 255, 255, 255))
img = img.minify(2)

img.save("out.png")

In the PNG file exported above, the background color is #FCFCFC (252, 252, 252).

Float precision ?

Hi

Thanks for flippy I have been using it on a few projects lately.
I was wondering if there is a plan to add float precision images?

Thanks

flippy.nim(1, 22) Error: cannot open file: chroma/blends

When I run nimble test with the latest version I get this error:

$ nimble test
  Verifying dependencies for [email protected]
      Info: Dependency on vmath@>= 0.3.2 already satisfied
  Verifying dependencies for [email protected]
 Installing chroma@>= 0.1.5
Downloading https://github.com/treeform/chroma using git
  Verifying dependencies for [email protected]
 Installing [email protected]
   Success: chroma installed successfully.
      Info: Dependency on nimPNG@>= 0.2.6 already satisfied
  Verifying dependencies for [email protected]
      Info: Dependency on supersnappy@>= 1.0.0 already satisfied
  Verifying dependencies for [email protected]
      Info: Dependency on bumpy@>= 0.2.1 already satisfied
  Verifying dependencies for [email protected]
      Info: Dependency on vmath@>= 0.4.0 already satisfied
  Verifying dependencies for [email protected]
  Compiling /Users/matt/lib/flippy/tests/test (from package flippy) using c backend
/Users/matt/lib/flippy/src/flippy.nim(1, 22) Error: cannot open file: chroma/blends
       Tip: 26 messages have been suppressed, use --verbose to show them.
     Error: Execution failed with exit code 256
        ... Command: /Users/matt/.nimble/bin/nim c --noNimblePath -d:NimblePkgVersion=0.4.7 --path:/Users/matt/.nimble/pkgs/vmath-0.4.0 --path:/Users/matt/.nimble/pkgs/chroma-0.2.1 --path:/Users/matt/.nimble/pkgs/nimPNG-0.3.1 --path:/Users/matt/.nimble/pkgs/supersnappy-2.0.0 --path:/Users/matt/.nimble/pkgs/bumpy-0.2.1 --path:/Users/matt/.nimble/pkgs/vmath-0.4.0 --hints:off -r --path:. /Users/matt/lib/flippy/tests/test

image.putRgba issue or user error ?

Hi,

Trying this simple test does not seem to work on OSX, Am I using it wrong 🙈 ?

import flippy, chroma

const w = 128
const h = 128

proc flipTest*() = 
  var image = newImage(w,h,4)
  for x in {0..w-1}:
    for y in {0..h-1}:
      if x < int(w/2):
        image.putRgba(x, y, rgba(255, 0, 0, 255))
      else:
        image.putRgba(x, y, rgba(0, 0, 255, 255))
  image.save("test.png")

image

Error: undeclared identifier: 'Rect'

Thanks for this great library!

This error is on Linux (docker nim-lang/nim:1.4.2). The same code seems to work fine on macOS

# cat foo.nim 
import os
import flippy

proc resizePNG*(src:string, dst:string, width:int, height:int) =
  loadImage(src).resize(width, height).save(dst)

when isMainModule:
  resizePNG(paramStr(1), paramStr(2), 100, 100)
# nim c foo.nim 
Hint: used config file '/nim/config/nim.cfg' [Conf]
Hint: used config file '/nim/config/config.nims' [Conf]
........................................
/root/.nimble/pkgs/flippy-0.4.7/flippy.nim(311, 42) Error: undeclared identifier: 'Rect'
# nimble list -i
chroma  [0.1.5]
flippy  [0.4.7]
nimPNG  [0.3.1]
supersnappy  [2.0.0]
vmath  [0.4.0]
# nim --version
Nim Compiler Version 1.4.2 [Linux: amd64]
Compiled at 2020-11-30
Copyright (c) 2006-2020 by Andreas Rumpf

git hash: 3fb5157ab1b666a5a5c34efde0f357a82d433d04
active boot switches: -d:release -d:danger
# uname -a
Linux 883414a58802 5.4.39-linuxkit #1 SMP Fri May 8 23:03:06 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Getting an error when running the basic usage example: Error: undeclared identifier: 'rgba'

Hi, thank you for writing this library. I tried compiling the basic example:

import flippy
# load an image
var image = loadImage("tests/lenna.png")
# print it out
echo image
# get a color pixel
echo image.getRgba(100, 100)
# put a color pixel
image.putRgba(10, 10, rgba(255, 0, 0, 255))
# blit a rectangular part from one place to another
blit(image, image, rect(0, 0, 100, 100), rect(100, 100, 100, 100))
# draw a line
image.line(vec2(11, 11), vec2(100, 100), rgba(0, 0, 0, 255))
# minify image by 2 or 1/2 or scale by 50%
image = image.minify(2)
# save the image to a file
image.save("tests/lenna2.png")

I use nim c flippy_test.nim and this is the output:

Hint: used config file '/Users/owner/.choosenim/toolchains/nim-1.4.0/config/nim.cfg' [Conf]
Hint: used config file '/Users/owner/.choosenim/toolchains/nim-1.4.0/config/config.nims' [Conf]
......................................
/Users/owner/nim/flippy/flippy_test.nim(9, 23) Error: undeclared identifier: 'rgba'

My OS is macOS Catalina Version 10.15.6. I'm using Nim Compiler Version 1.4.0 [MacOSX: amd64].

I'm new to Nim, so perhaps I'm missing something pretty obvious... (having to do with the wrappers for the C image libraries being used or something like that? Really don't know. 😅) Also, it compiles if I take out the lines that use rgba, vec2, and rect parameters.

STBI Exception

When trying to use fllippy to minify an image I keep getting an error on

loadImage
stb_image\read.nim(91) load
Error: unhandled exception: can't fopen [STBI Exception]

How did I call?
var a = reduceImage("C:\\Nim\\NimExamples\\MyRecipes\\a.png", "C:\\Nim\\NimExamples\\MyRecipes\\b.png", 3)
against proc

proc reduceImage*(inFile: string, outFile: string, scale: cint): cint {.cdecl, exportc, dynlib.} =
  ## reduces image
  var image = loadImage(inFile)
  image = image.minify(scale)
  image.save(outFile)
  result = scale

Is it my own stupidity, or is it a real issue? I am on windows as you probably guessed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.