JSPM

  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q96491F
  • License MIT

SIMDope 🎨 - Color trafficking library faster than tools not mentioning it, lighting fast and around 1700 lines of code (~7kB Gzipped and 0 dep.)

Package Exports

  • simdope
  • simdope/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (simdope) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

SIMDope 5.1.0

A Color Trafficking Library Designed for Lightning-Fast Processing

MIT License

SIMDope Branding Logo

SIMDope is a library that optimizes color processing by leveraging arrays of bytes and specialized classes. The primary class, SIMDope.Colors, enhances performance when working with color lists. The secondary class, SIMDope.Color, facilitates transformation, conversion, and operations on individual colors. Notably, elements retrieved from a new instance of SIMDope.Colors are not copied, contributing to its exceptional speed and reduced burden on the garbage collector.

Performance

SIMDope Performance NPM Downloads

Instead of copying elements, a view of the TypedArray colors data is obtained, allowing for faster operations. Changes made to retrieved elements are reflected in the original TypedArray, resulting in optimized performance.

Fun Fact

Using our color quantization algorithm (coming soon to NPM), we can reduce 250K colors to 1K in just 0.3-0.4 seconds. The capability to blend them all together is truly remarkable. A canvas of 512x512 is approximately 250K pixels, yet this library handles multiple millions of operations per second. It is expected to be 4-16 times faster than most other libraries, thanks to SIMD JS & ASM JS!

How to Use SIMDope.Color?

To understand its usage, especially given its performance-oriented nature, refer to the source code. However, here are various ways to create a new color object.

Installing the Library

npm install simdope

Importing the Library

Browser

// Use the file located in /dist/index.min.js for proper polyfill support (pre-Chrome 61.0)
var Color = window.SIMDOPE.Color;
var Colors = window.SIMDOPE.Colors;

NodeJS

// Use the file located in / for compatibility with code processors like Babel
import { Color, Colors } from "simdope";

Installing the library

npm install simdope

Importing the library

Browser

// Use the file located in /dist/index.min.js because it has polyfills required for < Chrome 61.0 (September 5, 2017)
var Color = window.SIMDOPE.Color;
var Colors = window.SIMDOPE.Colors;

NodeJS

// Use the file located in / because it will be parsed properly by piece of code such as Babel
import {Color, Colors} from "simdope";

How to use SIMDope.Color?

🔧 Functions, Methods, and Properties of SIMDope.Color

Instantiate an object of the single color class

Color(with_main_buffer, offset_4bytes)
Color.new_zero()
Color.new_of(r, g, b, a)
Color.new_safe_of(r, g, b, a)
Color.new_from(agbr_array)
Color.new_array(rgba_array)
Color.new_array_safe(rgba_array)
Color.new_uint32(uint32) 
Color.new_uint32b(uint32b)
Color.new_hsla(h, s, l, a)
Color.new_hex(hex_anything)

🔍 Properties:

Property Description
color.r Red component (readonly)
color.g Green component (readonly)
color.b Blue component (readonly)
color.a Alpha component (readonly)
color.uint32 Integer representation (readonly)
color.uint32b Integer representation (readonly)
color.hex Hex representation (readonly)
color.hsla HSLA representation (readonly)
color.lab LAB color space (readonly)
color.ycbcra YCbCrA color representation (readonly)
color.skin Indicates if the color matches skin tones (Boolean)
color.tail Utility for chaining multiple colors before blending
color.hilbert Indicates the 1D (uint32) index of the RGB coordinates
color.rgbaon4bits RGBA on 4 bits representation (readonly)
color.rgbaon6bits RGBA on 6 bits representation (readonly)
color.rgbaon8bits RGBA on 8 bits representation (readonly)
color.rgbaon12bits RGBA on 12 bits representation (readonly)
color.offset Offset of the color data (readonly)
color.buffer_ Primary buffer (private; use methods for access)
color.subarray_ Provides a "pointer" instance without copying data (private)
color.slice_ Clones the data into a new Uint8Array (private)

🔍 Methods:

Get:

Method Description
color.get_buffer() Retrieve the primary buffer
color.get_subarray() Access the "pointer" instance of the color data
color.get_slice() Clone and retrieve the color data
color.sum_rgba() Sum of RGBA values
color.sum_rgb() Sum of RGB values
color.is_dark() Check if color is dark
color.is_skin() Check if color matches skin tones
color.is_fully_transparent() Check if color is fully transparent
color.is_fully_opaque() Check if color is fully opaque
color.is_not_skin() Check if color doesn't match skin tones
color.is_not_fully_transparent() Check if color isn't fully transparent
color.is_not_fully_opaque() Check if color isn't fully opaque

Set:

Method Description
color.set(with_buffer) Set the color using (Uint8Array or ArrayBuffer)
color.set_from_simdope(color) Set a color from a Color instance
color.set_from_array(new Uint8Array(4)) Set the color from an ABGR
color.set_from_buffer(with_buffer, offset_four_bytes) Reuse the instanced object
color.set_tail(simdope_instance, premultiply_alpha_255_optional) Set a tail
color.simplify(divider) Peg the color (e.g., 1.6, 2, 3.2)
color.blend_with(another_color, strength_on_255, should_return_transparent, is_alpha_addition) Blend
color.blend_first_with(another_color, strength_on_255, should_return_transparent, is_alpha_addition) Blend
color.blend_first_with_tails(is_alpha_addition) Blend color with tails then deletes tail links
color.match_with(another_color, threshold_on_255) Match color
color.manhattan_match_with(another_color, threshold_float) Match color using Manhattan algorithm
color.euclidean_match_with(another_color, threshold_float) Match color using Euclidean algorithm
color.cie76_match_with(another_color, threshold_float) Match color using CIE76 algorithm
color.set_r(r) Set red component to r
color.set_g(g) Set green component to g
color.set_b(b) Set blue component to b
color.set_a(a) Set alpha component to a
color.to_greyscale() Convert color to greyscale
color.to_greyscale_luma() Convert color to greyscale using luma

🔍 Functions:

Function Description
Color.with_r(color, r) Create a new color instance using color with specified red component r
Color.with_g(color, g) Create a new color instance using color with specified green component g
Color.with_b(color, b) Create a new color instance using color with specified blue component b
Color.with_a(color, a) Create a new color instance using color with specified alpha component a
Color.with_inverse(color) Create a new color instance with inverted colors of color
Color.with_match(color_a, color_b, threshold_on_255) Match two colors color_a and color_b with a threshold threshold_on_255
Color.blend(color_a, color_b, strength_on_one, should_return_transparent, is_alpha_addition) Blend two colors color_a and color_b with strength_on_one, should_return_transparent, and is_alpha_addition

Please, look at the source code to know more about other cool ways of using it ...

How to use SIMDope.Colors?

🔧 Functions, Methods, and Properties of SIMDope.Colors

🔍 Properties:

Property Description
colors.length Number of colors in the list (readonly)
colors.buffer Buffer containing the color data (readonly)

🔍 Methods:

Get:

Method Parameters Description
colors.get_element(index, old_color_object_optional_faster) index: Position of color in the list
old_color_object_optional_faster: (Optional) Previous color object for faster access
Retrieve the color at a specified index. When you get an element and apply changes, it updates the color within your list's buffer.
colors.subarray_uint32(start, end) start: Start index
end: End index
Get a subarray from the Uint32Array representation
colors.slice_uint32(start, end) start: Start index
end: End index
Get a slice from the Uint32Array representation
colors.subarray_uint8(start, end) start: Start index
end: End index
Get a subarray from the Uint8Array representation
colors.slice_uint8(start, end) start: Start index
end: End index
Get a slice from the Uint8Array representation
colors.get_deduplicated_uint32a() None Removes duplicate uint32 entries. May need polyfills for older browsers.
colors.get_deduplicated_sorted_uint32a() None Use a high-performance 8bits 3D Hilbert curve algorithm to sort and remove duplicates on one dimension.

Set:

Method Parameters Description
colors.set_element(index, color_object) index: Position in the list to set the color
color_object: The color object to set
Set a color at the specified index
colors.buffer_setUint8(index, number) index: Position in the buffer to set the byte
number: Byte value to set
Set a byte in the buffer
colors.buffer_setUint32(index, number) index: Position in the buffer to set the Uint32 value
number: Uint32 value to set
Set a Uint32 value in the buffer

How it should be used (LOOK HERE)

var white = Color.new_of(255, 255, 255, 255);
var green = Color.new_of(0, 255, 0, 255);
var red = Color.new_of(255, 0, 0, 255);

var simdope_my_colors = Colors(imagedata);
    // That rewrite the inner data of our array but also white if we don't copy it
    simdope_my_colors.get_element(0).blend_with(white.copy(), 192, false, false);
    simdope_my_colors.get_element(1).blend_with(white, 0.25*255, false, false) ;

simdope_my_colors.get_element(2)
    .blend_with(white.copy(), 0.25*255, false, true)
    .blend_with(green.copy(), 0.75*255, false, true)
    .blend_with(red.copy(), 0.25*255, false, true)
    
var purple = simdope_my_colors.get_element(2);
var purple_copy = purple.copy();
var purple_hex = purple.hex;
var purple_uint32 = purple.uint32;
var is_purple_dark = purple.is_dark();
var is_purple_dark_but_from_hex = Color.new_hex(purple_hex).is_dark();
var purple_alpha_but_from_uint32 = Color.new_uint32(purple_uint32).a;

var some_uint32array_colors = simdope_my_colors.subarray_uint32(0, 3);
var some_colors = new Colors(some_uint32array_colors.buffer);

  some_colors.set_uint32_element(0, purple.uint32);
  some_colors.set_uint32_element(1, purple.uint32);

For more usage scenarios, explore the source code.

Please refer to the source code for additional information and advanced usage scenarios.