|
final presentation
4.05.05
re-canyon
The inspiration for this work, comes from the tradition of landscape representation in art, deconstructed landscape
by painters such as Mark Tansy, the video art work of Bill Viola, philosophical writing of Barthes (Mythologies),
Baudrillard (Simulacra and Simulation) and Huizinga (Homo Ludens) and a long standing personal interest in the mediated relationship
of nature.

final design - Projected image, enlarging the webcam. This addresses the image quality issue of the low-res web camera image.
In final design for re-canyon, pictured above, a person stands in front of a projected live webcam feed, with a camera
above detecting their proximity to the projection.
The proximity of the person activates the projected image. As the person stands closer to the projection, their distance correlates with
the speed of the 'degradation' of the top most image, and every consequent image beneath it. Over time each image 'disappears' till the final image in the
array is revealed. The next to last image in the array will be 'erased' if the person continues to watch, till only the last image remains.
The program then resets itself, and the topmost image fades back.
The following link shows a basic sketch done in processing, without any masking effect, which the final piece will employ.
grca proximity sketch
The following link shows the collected webcam images, using a custom written java webcam image scraper.
http://stage.itp.nyu.edu/~mjl359/netex/GrandCanyon/
I am currently in the process of combining code that collects webcam images, stores them in a directory, draws them
in a frame, which then draws an alpha mask through which the underneath images will become visible.
The final section of code will determine how the image is revealed based on an algorithm triggered by proximity of the user.
I am tring to achieve the effect seen in the images below.
The images below were created in Photoshop. The process of creating these images, gave me insight into the pseudo-code for the java program.
I learnt about the order in which to 'erase' the images, and the quantity of the image that needed to be erased. 'Erasing' in stages,
will result in a painterly subtle shift between the images, rather than boring straight through like a drill bit.
These images below are successful, in creating the aesthetic experience i am looking for.





|
Main Code:
package grancanHole;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JApplet;
import javax.swing.JFrame;
/*
* Created on Oct 1, 2004
*
* */
/**
* @author Dan O'Sullivan and somewhat Marta Lwin
*
* Gathers images from a web directory and displays them
*/
public class ScrapeandWrite extends JApplet { //this
// can be an applet or an application
boolean isApplet = true;
static JFrame frame;
ArrayList pics = new ArrayList();
int currentImage = 0;
int numberOfImages = 0;
int wormHoleX = 100;
int wormHoleY = 100;
int bigPicture = new bigPicture;
int wormx = new wormx;
public void init() {
getContentPane().setLayout(null);
//get list of names of images from web directory
ArrayList filenames = readWebDirectory("http://stage.itp.nyu.edu/~mjl359/netex/GrandCanyon/?M=D");
// gets actual image, stores image in an object, and puts object in an array
numberOfImages = Math.min(filenames.size(),360)-1;
currentImage = numberOfImages;
for (int i = 0; i< numberOfImages ;i++){
String filename = (String) filenames.get(i);
BufferedImage bi = new BufferedImage(640,480,BufferedImage.TYPE_INT_ARGB);
//BufferedImage bi = null;
Image img = null;
try {
//bi = (BufferedImage) getImage(new URL("http://stage.itp.nyu.edu/~mjl359/netex/GrandCanyon/"+ filename));
/* Couple of notes:
You can't call getImage unless you are running as an applet (in a webpage)
Otherwise, you call getToolkit().getImage
Also, you can't cast an image to a bufferedimage. You have to draw it on a buffered images graphics
Also, you can't do that unless you know that the image is fully loaded, hence the media tracker.
*/
URL aURL = new URL("http://stage.itp.nyu.edu/~mjl359/netex/GrandCanyon/" + filename);
if (isApplet)
{
img = getImage(aURL); // Running as an applet
}
else
{
img = getToolkit().getImage(aURL); // Running from the desktop
}
MediaTracker tracker = new MediaTracker(this);
tracker.addImage(img, 0);
tracker.waitForID(0); // Wait for the image to load
int iw = img.getWidth(this); // Get height
int ih = img.getHeight(this); // Get Width
bi = new BufferedImage(iw, ih, BufferedImage.TYPE_INT_RGB); // Create a buffered image of the same size
Graphics2D big = bi.createGraphics(); // Get the graphics of the buffered image
big.drawImage(img,0,0,this); // Draw the image onto the buffered image, in a sense, casting the hard way
big.dispose(); // Cleanup
// Now you have a buffered image called bi.
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
pics.add(bi);
System.out.println("added pic to arraylist");
}
repaint();
}
public void update(Graphics g){ //overrid java's clean up of the screen becaus you are fill the screen anyway, faster, less flicker
paint(g);
}
public void paint(Graphics g) { //this is where we paint
if (pics.size() > 0) {
currentImage = 0;
currentImage = currentImage -1; //change 1 to vary speed
if (currentImage <0 ) currentImage = numberOfImages;
if (currentImage == numberOfImages ) currentImage = 0;
BufferedImage otherImage = new BufferedImage(640,480,BufferedImage.TYPE_INT_ARGB);
otherImage = (BufferedImage) pics.get(currentImage);
g.drawImage(otherImage,0,0,640,480,this);
//BufferedImage smallOne = otherImage.getSubimage(wormHoleX,wormHoleY,40,40);
//g.drawImage(smallOne,wormHoleY,wormHoleX,40,40,this);
BufferedImage bi = bigPicture.subimage(wormx,wormy,40,40);
BufferedImage ahole= new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D aholeGraphics = (Graphics2D) ahole.getGraphics();
aholeGraphics.drawImage(_alphaMask, 0, 0, bi.getWidth(), bi.getHeight(), null);
aholeGraphics.setComposite(AlphaComposite.SrcIn);
aholeGraphics.drawImage(bi, 0, 0, null);
g.drawImage(ahole, wormx, wormy, 40, 40, null);
}
}
public void destroy() {
if (isApplet == false) {
System.out.println("Kill Application");
frame.setVisible(false);
frame.dispose();
System.exit(0);
}
}
public void stop() {
}
public static void main(String[] args) {
//this is called when it is an application
final ScrapeandWrite applet = new ScrapeandWrite();
applet.isApplet = false;
frame = new JFrame();
frame.addWindowListener(new java.awt.event.WindowAdapter() {
public void windowClosing(java.awt.event.WindowEvent e) {
applet.stop();
applet.destroy();
}
});
frame.setTitle(applet.getClass().getName());
frame.getContentPane().add(applet, BorderLayout.CENTER);
frame.setSize(640,480);
frame.setVisible(true);
applet.init(); //call the applet stuff
applet.start();
}
public BufferedImage makeAlphaMask() {
BufferedImage _alphaMask = new BufferedImage(120, 160, BufferedImage.TYPE_INT_ARGB);
Point midPoint = new Point(_alphaMask.getWidth() / 2, _alphaMask.getHeight() / 2);
int alpha;
for (int i = 0; i < _alphaMask.getHeight(); i++) {
for (int j = 0; j < _alphaMask.getWidth(); j++) {
float d = (float) Math.abs(midPoint.distance(j, i));
if (d > _alphaMask.getWidth() / 2) {
alpha = 0;
}
else {
float percentAway = 3/2*d / (float) (_alphaMask.getWidth());
alpha = 255- Math.max(50, Math.min(240, (int) (255 * (percentAway)))); //(int) Math.max(0,Math.min(255,(255*percentAway)));
}
_alphaMask.setRGB(j, i, 0x01000000 * alpha);
}
}
return _alphaMask;
}
public ArrayList readWebDirectory(String _dir){
ArrayList pics = new ArrayList();
try{
URL myURL = new URL(_dir);
BufferedReader dis = new BufferedReader(new InputStreamReader(myURL.openStream()));
//InputStreamReader isr = new InputStreamReader(myURL.openStream())
String line = dis.readLine();
boolean ignore = true;
while(line != null)
{
System.out.println("get existing " + line);
if(line.indexOf("")!= -1){
ignore = true;
}
if (ignore == false){
String frontMark = "";
int beg = line.indexOf(frontMark) + frontMark.length();
int end = line.indexOf("\"",beg);
//System.out.println("----" + line.substring(beg,end));
pics.add(line.substring(beg,end));
}
if(line.indexOf("Parent Directory")!= -1){
ignore = false;
}
line = dis.readLine();
}
}catch (IOException e){System.out.println("BAD URL");}
return pics;
}
}
java web scraper code (reusable):
package grancanHole;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.awt.FileDialog;
/*
* Created on Apr 15, 2005
*
* TODO To change the template for this generated file go to
* Window - Preferences - Java - Code Style - Code Templates
*/
/**
* @author admin
*
* TODO To change the template for this generated type comment go to
* Window - Preferences - Java - Code Style - Code Templates
*/
public class GetCan2 {
static WebCamScraper myScraper;
GetCan2() {
}
static public void main(String[] args){
//send the url and local folder to put it in, "." means current folder,"\\" means "\" different for the mac
//System.out.println("HI!");
//File fout = new File("./gc/index.txt");
/*String path = "Ganesh/Users/martalwin/Documents/Processing/GRCA3/data";
path = path.replace('/', File.separatorChar);
File mailbox = new File( path );
*/
myScraper = new WebCamScraper("http://www2.nature.nps.gov/air/webcams/parks/grcacam/grca.jpg","./GrandCanyon/",60*15);//"Ganesh:Applications:eclipse:workspace:Netex:grancanHole:GrandCanyon:");
//myScraper = new WebCamScraper("http://www2.nature.nps.gov/air/webcams/parks/grcacam/grca.jpg","path",60*14);//processimg folder
}
}
back
|