Toolbox Interactiondesign


Media Deconstructed

MEDIA DECONSTRUCTED: BENJAMIN HATSCHER

Farbpalette

Benjamin Hatscher, 11.03.2013 | Basics Computer Science 2012 bei Prof. Dr. Christine Goutrié

Aufgabe N°6

Entwerfen Sie ein Tool, um Medien zu dekonstruieren. Das kann Ihnen durch Vergleichen, Analysieren der verschiedenen Parameter gelingen. Dazu benötigen Sie eine Systematik, nach der Sie geeignete Parameter für den jeweiligen Medientyp visualisieren können.

Images Deconstructed.

Bilder oder Bilderfolgen in Videos zusammengefasst sind letztlich nur Sammlungen von Pixeln und deren Farbwerten. Was passiert, wenn diese festgelegten (zweidimensionalen) Strukturen durch Dekonstruktion aufgehoben werden? Entstehen immer noch Bilder oder ein neues Medienformat? Wie werden die Dimensionen von horizontal, vertikal, zeitlich aufgelöst? In welche Medien lassen sich Pixel übersetzen?

In der täglichen Medienflut bleiben von aufwändig produzierten Filmen oft nur noch Stimmungen zurück. „Media deconstructed“ nutzte ich dazu, Filme automatisch auf ihr einfachstes Wesen herunter zu brechen: Farbpaletten und die Dauer ihrer Sichtbarkeit. So entstand ein einfacher Analyseablauf.

In jedem Bild des Filmes werden eine feste Anzahl an Pixeln, bestimmt über einen Auflösungswert, herausgegriffen. Nach Helligkeit sortiert und aneinander gereiht ergibt sich bereits eine visuelle, zweidimensionale Repräsention des gesamten Filmes.

Der nächste Schritt fasst die Farbwerte in fünf Abstufungen zusammen. So verschwinden kleine Akzente, eine grobe, dafür leicht zu erfassende Farbwelt des Filmes bleibt zurück. Der zeitlichen Komponente Rechnung tragend, teilt ein Schwellenwert für Farbunterschiede zwischen Bildern die Länge der einzelnen Farbpaletten ein. So wird der Rhythmus des Filmes auf die grafische Darstellung übertragen.

import processing.video.*;
import processing.pdf.*;

//parameters
int resolution = 100;
boolean saveFrame=false;
int fileName=1;

//utils
Movie myMovie;
int lineCounter = 1;
int rowCounter = 1;
int formerAverage = 0;
int[][] colorFields = new int[5][3];
int paleteAverageCounter = 0;
float moviedurration;
float capturerate;
float capcounter =0;

void setup() {
  myMovie = new Movie(this, "dummyMovie.mp4");
  myMovie.frameRate(5);
 
  myMovie.play();
  moviedurration = myMovie.duration();
  //capturerate = (moviedurration*40);
  capturerate = 0.5;
  myMovie.noLoop();
  size(700, 500);
  loadPixels();
}


void draw() {  
     
  float smallWidth = float(myMovie.height)/190;
  if (smallWidth != 0) {
    smallWidth = myMovie.width/smallWidth;
    image(myMovie, 0, 0, smallWidth,200);
  }
  loadPixels();
}


void mousePressed() {
  saveFrame=true;        //pdf schreiben anschalten
}

// Called every time a new frame is available to read
void movieEvent(Movie m) {  
 m.read();
 if (capturerate < 1) {
   if (capcounter >= 1) {
     capcounter -= 1;
     frameProcessing(m);
   } else {
     capcounter+=capturerate;
   }   
 } else {
   if (capcounter >= capturerate) {
     capcounter = 0;
     frameProcessing(m);
   } else {
     capcounter++;
   }
 }
}

void frameProcessing(Movie m) {  
  
  int res = round(m.pixels.length/resolution);
  int average = 0;
  m.loadPixels();
  color[] tempPixelArray = new color[resolution];
  // store 'resolution' amount of pixels from VideoImage in tempArray
  for (int i = 0; i < resolution;i++) {
    int step = i*res;
    tempPixelArray[i] = m.pixels[step];
  }
  // sort tempArray
  tempPixelArray = sort(tempPixelArray);
  // set pixels on Screen to color at tempArray, one row per frame, side by side
  for (int j = 1; j<tempPixelArray.length;j++) {
    pixels[lineCounter+(width*(tempPixelArray.length+j+150))] = tempPixelArray[j];
    average += tempPixelArray[j];
    // summ all Values per chanel at the cresponding cell in colorFields
    colorFields[floor(j/(tempPixelArray.length/colorFields.length))][0] += red(tempPixelArray[j]);
    colorFields[floor(j/(tempPixelArray.length/colorFields.length))][1] += green(tempPixelArray[j]);
    colorFields[floor(j/(tempPixelArray.length/colorFields.length))][2] += blue(tempPixelArray[j]);
    rowCounter++;
  }
  // calculate average image-color
  average /= tempPixelArray.length;
  Boolean displayPalete = false;
  // set red dot beneath image if change of average image color is higher than 300000 - this indicates a cut
  if (abs(formerAverage - average) > 300000 || myMovie.time() >= myMovie.duration()-0.01) {
    pixels[lineCounter+(width*(tempPixelArray.length+260))] = #FF0000;
    displayPalete = true;
  }
  formerAverage = average;
  rowCounter = 1;
  lineCounter++;
  paleteAverageCounter++;
  updatePixels();
  
  if (displayPalete) {
    for (int l= 0; l< colorFields.length;l++) {
      for (int n = 0; n < 3; n++) {
        // calculate average color per chanel by dividing by number of colorvalues and last cut
        colorFields[l][n] /= paleteAverageCounter*(tempPixelArray.length/colorFields.length);
      }
      // draw palete
      fill(color(colorFields[l][0],colorFields[l][1],colorFields[l][2]));
      stroke(0,0);
      rect(lineCounter, (tempPixelArray.length+270)+20*l, -paleteAverageCounter, 20);
      //colorFields[l]
    }
    loadPixels();
    paleteAverageCounter = 0;
  }
  
}

Der nebenstehende Quellcode zeigt die Funktionsweise. Durch die Angabe des Dateinamens kann damit jeder beliebige Clip auf seine Parbpalette readuziert werden.

21.10.2014 | Benjamin Hatscher |