diff --git a/examples/iron-puzzle/iron-puzzle.png b/examples/iron-puzzle/iron-puzzle.png new file mode 100644 index 0000000..d5252fb Binary files /dev/null and b/examples/iron-puzzle/iron-puzzle.png differ diff --git a/examples/iron-puzzle/iron-puzzle.rkt b/examples/iron-puzzle/iron-puzzle.rkt new file mode 100644 index 0000000..b054399 --- /dev/null +++ b/examples/iron-puzzle/iron-puzzle.rkt @@ -0,0 +1,66 @@ +#lang planet dyoo/whalesong/base +(require (planet dyoo/whalesong/resource) + (planet dyoo/whalesong/image)) + +;; The Iron Image Puzzle +;; Part of the Nifty Assignments page by Nick Parlante. +;; http://nifty.stanford.edu/2011/parlante-image-puzzle/ + +;; To run this program locally on your machine under Google Chrome, you'll +;; probably need to use --allow-file-access-from-files to get around +;; the same-origin policy. The program should run normally if served on +;; a web server + +(define-resource iron-puzzle.png) + + +;; First, grab the image by its url. +(define distorted-image iron-puzzle.png) + + +distorted-image +(image-width distorted-image) +(image-height distorted-image) + +;; We will want to decompose the image into its individual pixels. We can use +;; image->color-list to do this. +;; To make experimenting with the pixels an easy thing to do, let?s write +;; a function that will let us ?map? across the pixels of an image +;; to get another image. +(define (image-transform an-image a-pixel-transform) + (local [(define colors (image->color-list an-image)) + (define new-colors (map a-pixel-transform colors))] + (color-list->image new-colors + (image-width an-image) + (image-height an-image) + 0 + 0))) + + +;; With image-transform in hand, we can apply a filter, +;; such as zeroing out the blue and green components like this: +(define (zero-blue-green a-color) + (make-color (color-red a-color) + 0 + 0)) +(define dark-image + (image-transform distorted-image zero-blue-green)) + +dark-image + + +;; The image is still a bit darkened. Let?s bump up the red component +;; by a factor of ten. +(define (red*10 a-color) + (make-color (* (color-red a-color) 10) + (color-green a-color) + (color-blue a-color))) +(define red-eye-image + (image-transform dark-image red*10)) + +;; And now we should be able to look at red-eye-image and recognize +;; the landmark. + +red-eye-image +(image-width red-eye-image) +(image-height red-eye-image) diff --git a/image/private/kernel.js b/image/private/kernel.js index 386a5f3..0ee63e9 100644 --- a/image/private/kernel.js +++ b/image/private/kernel.js @@ -1437,7 +1437,7 @@ var imageToColorList = function(img) { a = data[i+3]; colors.push(makeColor(r, g, b, a)); } - return plt.baselib.lists.makeList.apply(null, colors); + return plt.baselib.lists.arrayToList(colors); } diff --git a/js-assembler/runtime-src/baselib-contmarks.js b/js-assembler/runtime-src/baselib-contmarks.js index 373b17f..11851d5 100644 --- a/js-assembler/runtime-src/baselib-contmarks.js +++ b/js-assembler/runtime-src/baselib-contmarks.js @@ -43,7 +43,7 @@ } } } - return baselib.lists.makeList.apply(null, result); + return baselib.lists.arrayToList(result); }; // Returns an approximate stack trace. diff --git a/resource/specialize/js-impl.js b/resource/specialize/js-impl.js index 4a6708b..538eff6 100644 --- a/resource/specialize/js-impl.js +++ b/resource/specialize/js-impl.js @@ -31,10 +31,10 @@ var isImagePath = function(s) { // A lot of this comes from image/private/kernel.js -var injectImageMethods = function(r, img) { +var injectImageMethods = function(r, img, after) { r.img = img; - r.getHeight = function() { return img.width; }; - r.getWidth = function() { return img.height; }; + r.getWidth = function() { return img.width; }; + r.getHeight = function() { return img.height; }; r.getBaseline = function() { return img.height; }; r.updatePinhole = function() { var aCopy = plt.baselib.clone(this); @@ -43,20 +43,29 @@ var injectImageMethods = function(r, img) { return aCopy; }; r.render = function(ctx, x, y) { - installHackToSupportAnimatedGifs(r); ctx.drawImage(r.animationHackImg, x, y); }; r.toDomNode = function(params) { return img.cloneNode(true); }; + + installHackToSupportAnimatedGifs(r, after); }; -var installHackToSupportAnimatedGifs = function(r) { - if (r.animationHackImg) { return; } +var installHackToSupportAnimatedGifs = function(r, after) { r.animationHackImg = r.img.cloneNode(true); document.body.appendChild(r.animationHackImg); r.animationHackImg.width = 0; r.animationHackImg.height = 0; + + if (r.animationHackImg.complete) { + after(); + } else { + r.animationHackImg.onload = function() { + delete (r.animationHackImg.onload); + after(); + }; + } }; @@ -79,10 +88,12 @@ EXPORTS['specialize!'] = makeClosure( rawImage.onload = function() { delete(rawImage.onload); delete(rawImage.onerror); - injectImageMethods(resource, rawImage); - restart(function(MACHINE) { - return finalizeClosureCall(MACHINE, resource); - }); + var after = function() { + restart(function(MACHINE) { + return finalizeClosureCall(MACHINE, resource); + }); + }; + injectImageMethods(resource, rawImage, after); }; rawImage.onerror = function(e) { delete(rawImage.onload);