Processingで動画をドット絵ムービーに変換するソフトを作ってみました

 タイトルまんまです、前作った「写真や画像をドット絵に変換するソフト」をいじって動画にしてみました。想像通りの出来で、特にどうということもなかったのですが、せっかく作ったので公開します。


 ドット絵ムービー


 ドット絵にする前の動画

ソースコードと使い方

 起動させると、選択画面になるので加工したい動画を選択。後は自動的に動画の生成がスタートします。スペースキーを押すと動画の生成が完了して終了します。
 動画を扱うので、Processingの他にOpenCVのライブラリのダウンロードを忘れないようにして下さい。

import hypermedia.video.*;
import processing.video.*;

int fps = 30;

OpenCV opencv;
MovieMaker mm;

PImage img0;
PImage writeImg;

//Window Size
int size_x = 128;
int size_y = 72;
int dotframe = 1;
int scale = 12;

void setup() {
  size(size_x*scale, size_y*scale);

  println("select movie."); 
  String moviePath = selectInput();

  opencv = new OpenCV( this );
  opencv.movie(moviePath, size_x*scale, size_y*scale);

  mm = new MovieMaker(this, size_x*scale, size_y*scale, "dotmovie.mov", fps, MovieMaker.VIDEO, MovieMaker.LOSSLESS); 
  frameRate(fps);
  writeImg = createGraphics(size_x*scale, size_y*scale, P2D);
}

void draw(){
  opencv.read();
  img0 = opencv.image();

  img0.loadPixels();

  // Making Image-----
  float[] img_r = new float[img0.width*img0.height];
  float[] img_g = new float[img0.width*img0.height];
  float[] img_b = new float[img0.width*img0.height];

  float[] img16_r = new float[size_x*size_y];
  float[] img16_g = new float[size_x*size_y];
  float[] img16_b = new float[size_x*size_y];

  for(int i = 0; i < img0.width*img0.height; i++){
    color tmp_color = img0.pixels[i];
    img_r[i] = red(tmp_color);
    img_g[i] = green(tmp_color);
    img_b[i] = blue(tmp_color);
  }

  int div_x = int(img0.width / size_x);
  int div_y = int(img0.height / size_y);

  float tmp_r;
  float tmp_g;
  float tmp_b;

  // make dot image
  for(int i = 0; i < size_x*size_y; i++){
    tmp_r = 0;
    tmp_g = 0;
    tmp_b = 0;
    int tmp_y = int(i / size_x);
    int tmp_x = i - size_x*tmp_y;

    for(int j = 0; j < div_x; j++){
       for(int k = 0; k < div_y; k++){
         tmp_r += img_r[tmp_x*div_x + tmp_y*img0.width*div_y+ j + k*img0.width];
         tmp_g += img_g[tmp_x*div_x + tmp_y*img0.width*div_y+ j + k*img0.width];
         tmp_b += img_b[tmp_x*div_x + tmp_y*img0.width*div_y+ j + k*img0.width];
       }
    }

    tmp_r = tmp_r/(div_x*div_y);
    tmp_g = tmp_g/(div_x*div_y);
    tmp_b = tmp_b/(div_x*div_y);
    
    img16_r[i] = tmp_r;
    img16_g[i] = tmp_g;
    img16_b[i] = tmp_b;
  }

  // scaling dot image
  writeImg.loadPixels();
  for(int i = 0; i < size_x*size_y; i++){
    int tmp_y = int(i / size_x);
    int tmp_x = i - size_x*tmp_y;

    for(int j = 0; j < scale; j++){
      for(int k = 0; k < scale; k++){
        writeImg.pixels[tmp_y*size_x*scale*scale+tmp_x*scale+j*size_x*scale+k] = color(img16_r[i], img16_g[i], img16_b[i]);
      }
    }
  }


  // draw frame
  for(int i = 0; i < size_x*size_y; i++){
    int tmp_y = int(i / size_x);
    int tmp_x = i - size_x*tmp_y;

    for(int j = scale-dotframe; j < scale; j++){
      for(int k = 0; k < scale; k++){
        writeImg.pixels[tmp_y*size_x*scale*scale+tmp_x*scale+j*size_x*scale+k] = color(255, 255, 255);
      }
    }
  }

  for(int i = 0; i < size_x*size_y; i++){
    int tmp_y = int(i / size_x);
    int tmp_x = i - size_x*tmp_y;

    for(int j = 0; j < scale; j++){
      for(int k = scale-dotframe; k < scale; k++){
        writeImg.pixels[tmp_y*size_x*scale*scale+tmp_x*scale+j*size_x*scale+k] = color(255, 255, 255);
      }
    }
  }

  writeImg.updatePixels();
  image(writeImg, 0, 0, width, height);

  mm.addFrame(); 
}


void keyPressed() {
  if (key == ' ') { 
  mm.finish(); 
  println("save movie."); 
  exit();
  }
}