////////// 定義された数値(ユーザーは基本編集しない) //////////////////// color scanColor = color(0, 0, 255); // 走査線の色 int RefreshTimeScan = 30; // 1秒間に再描画する回数(1 秒間に走査線が下るドット数) int RefreshTimeSlide = 40; // 1秒間に再描画する回数(1 秒間に走査線が下るドット数) ////////// 変数(ユーザーは編集しない) //////////////////// int scanY = 1; // 走査線のy位置 color[] scanImage; color[] scannedScreen; // 走査線が通った後の状態 boolean step_scanning; // 走査中かどうか(走査していないときは上へ移動) void scan_setup(){ scannedScreen = new color[width * height]; // 新しく生成 scanImage = new color[width * height]; // 新しく生成 scan_reset(); loop(); } void scan_reset() { frameRate(RefreshTimeScan); // フレームレートの設定 scanY = 1; // 走査線の初期位置 for(int i = 0; i < width * height; i++){ scannedScreen[i] = color(255); // 背景色で塗りつぶす scanImage[i] = color(255); } step_scanning = true; loop(); } void scan_draw(){ background(255); loadPixels(); drawMethod(scanImage); updatePixels(); } void drawMethod(color scr[]){ if(step_scanning){ // 走査線が下る。引数に、入力ビデオのピクセル情報を与える scan(scr); frameRate(RefreshTimeScan); } else{ // 走査結果が上る slide(); frameRate(RefreshTimeSlide); } } //////////////////// scan ////////////////////////////// void scan(color scr[]) { // 走査線の2つ上は、前回の結果を使う if(scanY >= 2){ for(int i = 0; i < width; i++){ for(int j = 0; j < (scanY - 2); j++){ pixels[i + j * width] = scannedScreen[i + j * width]; } } } // 走査線のすぐ上を走査 if(scanY >= 1) scanning(scr, scanY - 1); // 現在の描画状態を保存 pixelCopy(scanY - 1); // 走査線を描画 scanLine(scr, scanY); // 終了条件 if( scanY > height-10){ step_scanning = false; scanLine(scr, scanY); pixelCopy(scanY); scanY -= 1; frameRate(1); // 少し間を持たせる } // 走査線を1ドット下へ scanY++; } //////////////////// 走査線のすぐ上の走査 ////////////////////////////// void scanning(color scr[], int y) { boolean boolBg = true; // 背景内走査中はtrue for(int i = 0; i < width; i++){ if(boolBg && !bgColor(scr[i + y * width]) ){ // 現在背景走査中。オブジェクトを見つけた! boolBg = false; pointColor(i, y); } else if(!boolBg && bgColor(scr[i + y * width]) ){ // 現在オブジェクト走査中。背景を見つけた! boolBg = true; pointColor(i, y); } } } //////////////////// 走査線の描画 ////////////////////////////// void scanLine(color scr[], int y) { boolean boolBg = true; // 背景内走査中はtrue for(int i = 0; i < width; i++){ // 現在背景走査中 if(boolBg){ // 線を引き続ける pixels[i + (y - 1) * width] = scanColor; pixels[i + y * width] = scanColor; // オブジェクトを見つけた! if(!bgColor(scr[i + y * width]) ) boolBg = false; } // 現在オブジェクト走査中 & 背景を見つけた! else if(!boolBg && bgColor(scr[i + y * width]) ){ boolBg = true; } } } //////////////////// 指定箇所周囲 4ドットを塗りつぶす ////////////////////////////// void pointColor(int x, int y) { for(int i = x - 2; i <= x + 1; i++){ for(int j = y - 2; j <= y + 1; j++){ pixels[i + j * width] = scanColor; } } } //////////////////// 現在の描画状態を保存する ////////////////////////////// void pixelCopy(int y){ for(int i = 0; i < width; i++){ for(int j = y - 1; j <= y; j++){ if(j < 0) j = 0; scannedScreen[i + j * width] = pixels[i + j * width]; } } } //////////////////// 背景判定 ////////////////////////////// // 入力画像(ドット)から、背景かどうかを判定 boolean bgColor(color c) { if(c == scanColor) return true; if(c == color(255)) return true; return false; /* // 白かったら背景 if(c == color(255, 255, 255)) return true; else return false;*/ } //////////////////// slide ////////////////////////////// void slide() { for(int i = 0; i < width; i++){ // スキャン結果 for(int j = 0; j < scanY; j++){ pixels[i + j * width] = scannedScreen[i + (j + 1) * width]; } // 現状をコピー for(int j = 0; j < height; j++){ scannedScreen[i + j * width] = pixels[i + j * width]; } } scanY--; if(scanY < 0) noLoop(); // 終了 } //////////////////// はじめとおわり ////////////////////////////// void scan_start(){ loadPixels(); for(int i = 0; i < width * height; i++){ scanImage[i] = pixels[i]; } } void scan_end(){ loadPixels(); for(int i = 0; i < width * height; i++){ pixels[i] = scanImage[i]; } updatePixels(); scan_reset(); }