Skip to content

Instantly share code, notes, and snippets.

@jsundram
Last active December 16, 2015 13:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsundram/5441782 to your computer and use it in GitHub Desktop.
Save jsundram/5441782 to your computer and use it in GitHub Desktop.
Follow the instructions in Readme.md to use this.

This code allows you to open up an image file and replace its pixels with stars as you move the mouse over the screen. Useful, right?

  1. Download and unzip gist from https://gist.github.com/jsundram/5441782/download
  2. Navigate to folder you unzipped this code to in Terminal
  3. chmod +x install.sh
  4. ./install.sh (this will take a while)
  5. python starry.py "filename.jpg" from the command line. Press Ctrl-S to save.
#!/bin/bash
# bootstrapping script
# tested via: virtualenv fresh && source fresh/bin/activate
if [ -f /usr/local/bin/brew ];
then
echo "homebrew found!"
else
echo "installing homebrew . . ."
ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"
fi
# need mercurial to get latest pyglet
brew install hg
# pip?
easy_install pip
# need a special pyglet
pip install hg+https://pyglet.googlecode.com/hg/
# install my special brand of nodebox
pip install git+https://github.com/jsundram/nodebox-opengl
# numpy
pip install numpy
#scipy
brew install gfortran
pip install scipy
# scikit-image (requires scipy)
pip install Cython
pip install PIL
pip install scikit-image
from __future__ import division
from nodebox.graphics import *
from numpy.random import randint # random.randint is v. slow
import numpy
import os, sys
import skimage.io
import skimage.transform
# necessary on windows to prevent pyglet.gl.ContextException: Unable to share contexts?
os.environ['PYGLET_SHADOW_WINDOW']="0"
points = []
pic = None
pixels = None
def resize_image(filename):
"""Reads filename and resizes to fit screen"""
name, ext = os.path.splitext(filename)
# Did we already do this one?
resized = name + '_resized' + ext
if os.path.exists(resized):
print "using existing resized file:", resized
return resized
img = skimage.io.imread(filename)
ih, iw, ic = img.shape
sh, sw = canvas.screen.height - 80, canvas.screen.width
# Are we too small to bother resizing?
if ih < sh and iw < sw:
print "don't need to resize", filename, (ih, iw)
return filename
# Do the rescale:
print "resizing", filename
scale = min(sw / iw, sh / ih)
dw, dh = int(scale * iw), int(scale * ih)
i = skimage.transform.resize(img, (dh, dw))
skimage.io.imsave(resized, i)
print resized
return resized
def on_mouse_motion(canvas, mouse):
global points
if 0 < mouse.x < canvas.width and 0 < mouse.y < canvas.height:
inner = randint(5, 35)
outer = randint(inner, 45)
pts = randint(5, 9)
points.append((mouse.x, mouse.y, inner, outer, pts))
def setup():
global pic, pixels
print 'usage: python starry.py "/path/to/filename"'
print 'press control-s to save'
filename = sys.argv[1]
filename = resize_image(filename)
print 'loading ...'
pic = Pixels(Image(filename))
# Use a numpy array of pixels because pic.get is too slow to call repeatedly.
pixels = numpy.empty((pic.width, pic.height), dtype=Color)
for x in range(0, pic.width):
for y in range(0, pic.height):
pixels[x][y] = pic.get(x, y)
print 'done loading'
canvas.fps = 30
canvas.size = pic.size
nostroke()
canvas.on_mouse_motion = on_mouse_motion
canvas.run(draw)
def draw(canvas):
global pic, pixels, points
w, h = pixels.shape
for (x, y, i, o, p) in points:
star(x, y, points=p, outer=o, inner=i, fill=pixels[x][y])
image(pic, alpha=.2)
if __name__ == '__main__':
setup()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment