Nim stb_image Wrapper
This is a Nim wrapper of the stb_image single header file libraries
Official repo page can be found here: https://gitlab.com/define-private-public/stb_image-Nim
All other sites should be considered mirrors, though if you log an issue on GitHub, I'll probably address it.
The used header files are included in this repo (they end in the name
_header.nim) but you may provide your own.
The versions that are used are:
They can be found here: https://github.com/nothings/stb
If something is out of date or incorrect. Please notify me on the GitLab issue tracker so I can fix it. Though if something like a header file is out of date, you should be able to simply exchange it out (unless something was changed in the API).
For PNG support, stb_image requires a functioning zlib compressor/decompressor,
and one is built in. I'd like to thank RSDuck for exposing the functions with
some Nim friend wrappers. Se you want to see how to use it, check
for some samples.
Callback Functions & stbi_image_resize
Only the callback funtions for
stbi_image_write are implemented. I'd like to
thank Eduardo Bart (@edubart) for help on this. As for
felt that the scope of this wrapper should be focused on image loading and
saving, not processing.
Though if someone would like these included in the wrapper I am open to pull requests.
In the nature of Sean Barret (author of stb) putting his libraries in public
domain, so is this code. Specifically it falls under the "Unlicense." Please
check the file
LICENSE for details.
How To Use
I've tried to write this to be as close as possible to the orignal C API, so if
you're already familiar with it, there should be no hassle. If you don't all of
the functions are documented in
Import what you want to use. I recommend adding the
import stb_image/read as stbi import stb_image/write as stbiw
An original C call would look like this:
#include "stb_image.h" // Get the image data int width, height, channels; unsigned char *data = stbi_load("kevin_bacon.jpeg", &width, &height, &channels, STBI_default); // Do what you want... // Cleanup stbi_image_free(data);
But becomes this:
import stb_image/read as stbi var width, height, channels: int data: seq[uint8] data = stbi.load("kevin_bacon.png", width, height, channels, stbi.Default) # No need to do any GC yourself, as Nim takes care of that for you!
Functions that had names
like_this have been turned
portion has also been dropped.
If you want to write pixels, it's like what you see here, but in reverse:
import stb_image/write as stbiw # Stuff some pixels var data: seq[uint8] = @ data.add(0x00) data.add(0x80) data.add(0xFF) # save it (as monochrome) stbiw.writeBMP("three.bmp", 3, 1, stbiw.Y, data)
Some of the functions (or variables) that effect the library globally are still
stb_image), but some other has been
moved to functions calls as to not act in a global manor (e.g. the
I also recommend reading through the documentation at the top of the original
header files too, as they give you a bit more of a grasp of how things work and
the limitations of
All of the functions that can do image reading (which are, well, only found in
stb_image/read.nim) will throw an
STBIException if there was an error
retriving the image data. The
.message field of the exception will contain
some slight information into what went wrong.
Return a data structure that descrives an image instead of a sequence of bytes/shorts/floats from the functions. This may be a much more natural way for the programmer to get an image and make a little more sense than returning results in both the "return," statement and "var," parameters. Such a system might have a data structure like this:
type # `T` should only be uint8, uint16, or float32 STBImage[T]* = ref object of RootObj width*: int height*: int channels*: int # One of the values from `stb_image/components.nim` pixelData*: seq[T]
And the Nim-Friendly functions would change from this:
# Data var width, height, channels: int, pixels: seq[uint8] # Load the image pixels = stbi.load("kevin_bacon.jpeg", width, height, channels, stbi.Default)
Over to this:
var image = stbi.load("kevin_bacon.jpeg", stbi.Default)
It may also solve an issue with the pixel data being copied (unecessarly) with the current wrappers. See this thread in the Nim Forum for details: http://forum.nim-lang.org/t/2665
The only thing I don't like about this is that it would break the familiarity with the original C API. I don't want to maintain multiple functions that have the same functionality so I would be removing those orignal bindings.
Trying to figure out how to make the
STBImagetype play nice with the write functions might be a little more work too (e.g. validating there is enough data and correct parameters).
I'd like to get some comments on this before moving forward with it.
I really would like add unit tests for the functions listed in the
Untested Functionssection to verify they work, but I'm in need of some very simple test images.
Add wrappers/bindings for the
stb_image_resize.hlibrary. It's part of the STB toolkit (and falls under it's "image," section), but it wasn't related to image IO so I decided to leave it out. It also looked like quite a bit of work to add in. If someone wants to submit a pull request, I'll review it.
stbi_load_gif_from_memory isn't bound, but will be in the future.
See: https://gitlab.com/define-private-public/stb_image-Nim/issues/6 for details
on why this hasn't been added in yet.
All functions should have tests for them, but I wasn't able to find some test images (namely for the HDR) functions. So they do have bindings for completeness, but they haven't been proven to work. If you do happent to have some very simple test images I could use, please provide them. Here is the list of functions that are untested.
- Eduardo Bart (@edubart), for help with a segfault issue and write callback functions.