Portland Ketchup

I’m thrilled to see Portland Ketchup in the Oregon Museum of Science & Industry (OMSI), this place has always held a sweet place in my heart, it was (and continues to be) an adventure to visit; from the newest exhibits, to it’s oldest classics! Who could forget being part of a zero-gravity simulation, having their friends shock them with a hand-crank generator, or experiencing what it’s like to experience various types of earthquakes? There’s lizards, dry ice experiments, knowledge on the solar systems, a planetarium, the OMNIMAX, dinosaurs, games, and even a nuclear submarine. Keep up to date on the events calendar, there’s always something interesting going on at OMSI!

One of our main missions at Portlandia Foods is to provide a healthier alternative in public spaces. Because when people don’t have a choice, shouldn’t the only choice be a good one? I feel that Portlandia Foods has simply reset the clock in regards to ketchup, that is to say, Portland Ketchup is probably what ketchup tasted like in the 1920s; there was no High Fructose Corn Syrup (HFCS), or Genetically Modified (GMO) tomatoes. At Portlandia Foods, we use only the highest quality organic ingredients, and work hard to get those ingredients as locally as possible. I have to admit, our ketchup is pretty tasty… those tomatoes deserve all the credit though!!

My mom designed this beautiful poster for the OMSI cafeteria 🙂 See more of her work at BoniDeal.com

adminPortland Ketchup

Color Sphere

Color Sphere was one of my 1st HTML5 projects, way back in 2007. Well, the years passed, browsers sped up, my hair grew longer, and nothing changed on Color Sphere… but the time has come! The latest rendition is bigger (easier to see), more accurate (pixel perfect), and looks really cool when you switch it to Websafe mode and move the Saturation slider around 😉

The colors in Color Sphere are mapped to HSL. The luminance is the radius from the center, the hue is the angle, and the saturation controls the z-index; that is to say, the zoom into the HSL color space. Technically, it’s more of a color cylinder.

Head over to the Google Chrome Webstore and pick up the free browser app! Or access it online at Color Sphere. Let me know what you think about the changes! The old version can still be accessed for IE8 and below.

adminColor Sphere

Print-ready graphics in Canvas

Last month, I posted about the possibility of creating high-resolution and print-ready graphics in <canvas>. Since then, it’s been in the back of my mind, but happened to be at Kinko’s today, and decided to take this experiment to the next level… 😀

The following flash-cards were designed in Illustrator [by Altered Focus], exported into SVG, then parsed into <canvas>… and finally, that one template card (in the picture below it’s the “C” major card on the left) was used to create a large variety of combinations—based on a set of music-theory instructions. Such as;

Chord = { // definition for an A chord
	e1: false,
	a: { 0: true },
	d: { 2: 1 },
	g: { 2: 2 },
	b: { 2: 3 },
	e2: { 0: true }
}

The best thing is;  the designer can change the design in Illustrator and the design is automatically updated on the front-end, the programmer doesn’t even notice. I’m telling you, Illustrator is one bad-ass HTML5 editor 😉

There are a few bugs in my music-theory code (please excuse the improper fingering positions!), but, as you can see from the following 1,264 x 65,320 pixel image, you can create hundreds of variations of a single design. The nice thing is, I can find the bug in my code, fix it, and then updating hundreds of them takes about 30-seconds of CPU time!

Next step; find a good printer, and then get these cards into the local-guitar shops around Portland 😉

Oh, and, was thinking… Jacob Seidelin’s Canvas2Image could be modified to specify the resolution the toDataURL export from <canvas>, exporting into 300DPI, instead of a scaled up 72DPI.

Alternative route to convert from Illustrator to <canvas>

Although it’s not as versatile as a full-blown SVG-parser (as it’s a bit harder to modify the contents) you can get from Illustrator to <canvas> in a much quicker/easier way; AI-Canvas allows you to export from Adobe Illustrator directly into <canvas> paths, and even animations 😀

adminPrint-ready graphics in Canvas

Bitwise Gems and other optimizations

One of my favorite posts in the last few years was Bitwise Gems in AS3 by Polygonal Labs, an article inspired by Bitwise Operations in C on Gamedev. This article is a summery of what I’ve learned, applied to Javascript, plus a few other tricks.

What’s the wisdom in using bitwise?

Bitwise operations can be moderately faster than conventional methods. When processing a lot of data, even a 5% increase in speed can become noticeable. A good example of where you would want to use bitwise operations is in the pixel-manipulation of a <canvas> element, especially when dealing with larger dimensions. When you add up all speed improvements here, and then multiply that by each user that uses your application around the world, we could be talking about years of time saved! (in the collective sense) 😉

Standard operation on the (left) === (right) is bitwise or an alternative method such as replacing Math.max(a, b) with (a > b ? a : b). All speed results are measured in Javascript using Google Chrome 15. Without further ado;

Minimize calls to new Object() and new Array();
+/- 50% faster using flat-variables, not bitwise, but still wise.

var rgb = { R: 255, G: 0, B: 0 }; // slow.
var rgb = [ 255, 0, 0 ]; // faster by 40%
var R = 255, G = 0, B = 0; // faster by 50%
[2-23-2012] Updated as per Closure Compiler group discussion.
Rounding, flooring, and ceiling with bit-shifting;
+/- 20% faster using bitwise operations.

var n = Math.PI;
Math.round(n) === n + (n < 0 ? -0.5 : 0.5)>>0
Math.ceil(n) === n + (n < 0 ? 0 : 1) >> 0;
Math.floor(n) === n + (n < 0 ? -1 : 0) >> 0;

Or, if you’re certain the number will be positive (for example dealing with pixel values):

var n = Math.PI;
Math.round(n) === (n + 0.5) >> 0;
Math.ceil(n) === (n + 1) >> 0;
Math.floor(n) === n >> 0;

Storing mathematic constants in local variables;
+/- 15% faster than not doing it, just a reminder 😉

var E = Math.E;
var PI = Math.PI;
var SQRT2 = Math.SQRT2;
var SQRT1_2 = Math.SQRT1_2;
var LN2 = Math.LN2;
var LN10 = Math.LN10;
var LOG2E = Math.LOG2E;
var LOG10E = Math.LOG10E;

Fast modulo operation using bitwise AND (&);
+/- 15% faster using bitwise operations.

var numerator = 99999;
var divisor = 4; // divisor must be power of 2
(numerator % divisor) === (numerator & (divisor - 1));

Math.max & Math.min;
+/- 15% faster using alternate operations.

Math.max(a, b) === (a > b) ? a : b;
Math.min(a, b) ===  (a < b) ? a : b;

Math.abs;
+/- 10% faster using bitwise, or alternate operations.
The best solution here is not the bitwise operation, nor Math.abs().

var n = 99999;
var n = Math.abs(n);
var n = n > 0 ? n : -n; // +/- 10%
var n = (n ^ (n >> 31)) - (n >> 31); // +/- 3%

Test for even/uneven integers using bitwise AND;
+/- 10% faster using bitwise operations.

var n = 99999;
((n % 2) == 0) === ((n & 1) == 0);

Multiply by any power of two using left bit-shifting;
+/- 5% faster using bitwise operations.

var n = 99999;
(n * 2) === (n << 1);
(n * 64) === (n << 6);

Divide by any power of two using right bit-shifting;
+/- 5% faster using bitwise operations.

var n = 99999;
(n / 2) === (n >> 1);
(n / 64) === (n >> 6);

Swap integers without a temporary variable using XOR (^);
+/- 5% faster using bitwise operations.

var a = 1, b = 2;
// standard
var tmp = a;
a = b;
b = tmp;
// bitwise
a ^= b;
b ^= a;
a ^= b;

Sign flipping using NOT (~) or XOR (^);
+/- 2% faster using bitwise operations.

var n = 99999;
(-n) === (~n + 1);

HEX -> RGB conversion;

// 24-bit
var hex = 0x336699;
var r = hex >> 16;
var g = hex >> 8 & 0xFF;
var b = hex & 0xFF;

// 32-bit
var hex = 0xff336699;
var r = hex >> 24;
var g = hex >> 16 & 0xFF;
var b = hex >> 8 & 0xFF;
var a = hex & 0xFF;

RGB -> HEX conversion;

// 24-bit
var r = 0x33;
var g = 0x66;
var b = 0x99;
var hex = r << 16 | g << 8 | b;

// 32-bit
var r = 0x33;
var g = 0x66;
var b = 0x99;
var a = 0xff;
var hex = a << 24 | r << 16 | g << 8 | b;

Fast color conversion from R5G5B5 to R8G8B8 pixel format;

var R8 = (R5 << 3) | (R5 >> 2);
var G8 = (R5 << 3) | (R5 >> 2);
var B8 = (R5 << 3) | (R5 >> 2);

The speed-tests were done with the following code.

// lets pretend were running it on a image 1000x1000 pixels
var size = 1000 * 1000;
// example code
var bit1 = "Math.round(Math.PI)"; // standard
var bit2 = "(Math.PI + 0.5) >> 0"; // bitwise
// create the speedtest
function createFunction(f) {
	return '(function() { 
	   var t = (new Date()).getTime();
	   for (var n = 0; n < size; n ++) { '+f+' }
	   return t - (new Date()).getTime();
	});';
};
var timeFunctions = {
	a: eval(createFunction(bit1)),
	b: eval(createFunction(bit2))
};
var timeData = { };
//
function getAverage(type) {
	var loops = 10;
	var loopid = 0;
	var average = 0;
	function go() {
		if (loopid ++ == loops) {
			timeData[type] = average/loops;
			if (type == "a") { // get next
				setTimeout(function() { getAverage("b"); }, 1);
			} else { // complete
				var speedGain = ((timeData.a / timeData.b - 1) * 100 + 0.5);
				console.log(speedGain + "%");
			}
			return;
		}
		average += timeFunctions[type]();
		// setTimeout so browser can rest one loop
		setTimeout(function() { go(type); }, 1);
	};
	go();
};
setTimeout(function() { getAverage("a"); }, 1);

There are 10 loops * (1000×1000 pixels) = 10 million iterations are used to get the average execution speed of each function. setTimeout is clear the CPU, and prevent the previous loop from interfering with the next loop.

Further optimizations;

  • Replace Math.random with Park Miller (1988) “minimal standard” linear congruential pseudo-random number generator. This is also handy because the results are replicable by the seed you originally send it.
  • Pre-calculate as much math as possible;
    • var RAD2DEG = 180 / PI;
    • var DEG2RAD =  1 / RAD2DEG;
    • …and so on…
  • When using Color Matrices store the values of the matrix to local-variables (m0, m1, m2, m3… ect) before looping the pixels.
  • Use function calls sparingly; when speed is critical, instead of calling a function, use the contents of the function hard coded into your for() or while() loops. Choose where your line between readability, redundancy, and speed lies.

What optimizations do you use in your graphics or audio applications?

adminBitwise Gems and other optimizations

ColRD: Gradient Creator

Tonight, on ColRD, we released the latest rendition of Palette Creator, along with our newest addition; the Gradient Creator! This new webapp makes it fun and easy to create CSS3 linear gradients 🙂 UPDATE: You can also download the Gradient Creator as a Chrome webapp.

Features:

  • Drag & Drop GIMP Gradient (.GGR) files into the browser to view them!
  • Delta Swatch:  Shows the colors most similar to the one you’re choosing of the 4096 websmart colors (in CIE-Lab color space).
  • Keyboard goodness with Color Picker:  HSL, RGB, and HEX chooser.
  • Preview:  See your gradient in full-screen mode before you save it.
  • Flip:  Flip your gradient, so:  first is last, and last is first.
  • Intriguing new interface to create gradients! …

Do we need a new gradient editor GUI?

Gradient editors haven’t changed much historically, the same dynamic is used throughout GIMP, Illustrator, Inkscape and Photoshop. For me, these interfaces are clunky, leading to repetitive stress of the wrists and fingers, which prompted me to think, “There must be a better way!”.  One of the most click-saving changes was combining the Color Picker and Gradient Creator as one unit—there are no popup windows or “Ok” buttons.

Traditionally gradient editors allow users to place a point in space that radiates it’s color in both directions evenly. This is the way that computers think about gradients; color points in space, blended (in the case of <canvas>) linearly.

Description of the Gradient Creator;

  • ColRD gradient creator presents itself as color blocks—just like a palette.
    • Inside each color block you will find the midpoint controller—these controllers allow you to stretch the color towards the left or the right of the block.
    • To the left and right of the color block are col-resize controllers—these allow you to scale the width of the color block and the adjacent one.
  • Color blocks can be reorganized by dragging and dropping, without rescaling the color block or the ones around it.
  • If you drag and drop a color block onto the Color Picker, the color will be removed from your gradient (re-absorbed into color space!).

Future developments;

  • GGR, SVG, and CSS3 exporting (soon, as in this week).
  • Desktop wallpaper generator; textures, gradients, and user defined sizing (see previous article), along with the Gradient Noise generator.
  • Time-machine (undo and redo).
  • The user could split the midpoint, creating a shadow of itself in the opposite direction, this way the user could control the color blur on one edge (as it is now), or both edges simultaneously.  The shadow could be fixed to the inverse of the controller (SHIFT-KEY) to create even blurs, or controlled on it’s own independently.

If you have any ideas for the future, let us know!

Random thought;

For those interested in exotic gradient editors, SpectraG is a project that uses mathematic equations to generate gradients;

http://sourceforge.net/projects/spectrag/

adminColRD: Gradient Creator