feedly hatebu line pocket facebook twitter rss github pinterest muku

p5.jsで画像フィルタを作成する

processingの作品全然できねえ・・・。
ツイッターで毎日上げてるとか正気の沙汰じゃねえ・・・。
せや、フィルタ―やったら一回作ればいろいろ楽しめるやん!

という安直な考えではございますがなんとか無事に作れました!

参考資料はこちら

deconbatchさんのnote
楽しいよ! Processing でイメージプロセッシング
https://note.com/deconbatch/n/n8d341858ccdb

田所先生のメディアアート・プログラミング講義ノート
https://yoppa.org/geidai_media1_18/8916.html

p5.jsの導入と環境の整備

まずはp5.jsのコードを実行できる環境を整えましょー!
ウェブエディタ(https://editor.p5js.org) を利用するのが一番手っ取り早く使いやすいとは思うのですが、今回は画像をローカルから読み込むつもりなので別の方法にします。

index.htmlファイルとscript.jsファイルを作って実行するという形にしました。

p5.jsはこちらからCDNで読み込むことにします。
https://p5js.org/download/
CDN(Contents Delivery Network)
https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js

index.htmlファイルには次のように記入します。

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>p5.js Image Filter</title>
 <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
 <script src="https://cdn.jsdelivr.net/npm/p5@1.0.0/lib/p5.min.js"></script>
 <script src="script.js"></script>
</head>
<body>
 
</body>
</html>

同じ階層にscript.jsを置きます。
この中にコードを書いていきます。

ローカルでも動かせるエディタとかをちゃんとかければブラウザ上でコードを書いていくってこともできるんでしょうが、いろいろ調べてみて、コードを読んで挫折しました(-_-;)

また慣れてきたころにチャレンジしたいところです。
こういう挫折を味わうたびに、並行してjavascriptについてもちゃんと勉強しなきゃという気持ちになりますね…!

画像の読み込みをするときにはローカルのファイルを直接は読み込めず。サーバーから読み込まなければならないみたいです。(chromeのセキュリティの問題らしいですが、ここらへんの仕組みもまじでよくわかっていない…。)
今回は魔法だと思ってコマンドラインから作業しているフォルダに移動し、pythonでローカルサーバーを立ち上げました。

通常は画像をどこかにアップロードしてしまうのが手っ取りばやいと思います。

python -m http.server 8000

ブラウザからhttp://localhost:8000 にアクセスするとindex.htmlが自動的に開かれます。

参考はこちら:https://qiita.com/okhrn/items/4d3c74563154f191ba16

p5jsを利用して画像の表示

環境が整ったので、実際にscript.jsにコードをガリガリ書いて実際に画像を表示させて見ましょうー!
参考はこちら。

p5.js 画像の入出力と加工
https://scrapbox.io/tduyk/p5.js_画像の入出力と加工

こちらのページは画像の保存、読み込み、フィルターまでまとまっていて読みやすいです!

画像の読込と表示と保存

自分でも作ってみたコードを張っていきます。

let img;
let saveCounter=0;

function preload(){
  img = loadImage("cluster-of-daisies-699964.jpg")
}

function setup(){
  createCanvas(480,480);
  noStroke();
}

function draw(){
  background(124);

  imageMode(CENTER); //画像の位置を中心で指定
  image(img,240,240,440,440);
  noLoop();
}

function keyPressed(){
  if(key=='s'){
    saveCanvas('canvas'+saveCounter,'jpg');
    saveCounter++;
  }
}

loadImageで画像を読み込み、image()で画像をキャンバスに表示します。
キャンバスの保存はsaveCanvas()が利用できます。

loadImage()はpreload()の中に書く必要はありませんが、ちゃんと画像を読み込んでから実行されるためにはpreload()に書く方が望ましいかと思われます。

使用した画像:https://www.pexels.com/photo/cluster-of-daisies-699964/

染める(tint)

tintって染めるって意味なんですね。初めて見た・・・。

tint(R,G,B,Alpha)という感じみたいです。

let img;
let animateFlag=false;

function preload(){
  img = loadImage("cluster-of-daisies-699964.jpg");
}

function setup(){
 createCanvas(480,480);
 colorMode(HSB,360,100,100,100);
 background(50);
 noStroke();
}

function draw(){
 tint(frameCount*5%360,100,100,100);
 imageMode(CENTER); //位置を中心で指定
 image(img,240,240,440,440);
}

色相を徐々に変えるGif動画にしてみました。滑らかに色相は変わっていくはずだとおもうんですがどうもカクカクしてしまいますね。

フィルター

p5.jsにも標準でフィルタが装備しています。
https://p5js.org/reference/#/p5/filter

点描

let img;

function preload(){
  img = loadImage("cluster-of-daisies-699964.jpg");
}

function setup(){
  // 全体の設定
  createCanvas(480,480);
  noStroke();
  colorMode(HSB,360,100,100,100);
  background(60);

  img = resizeImg(img,width,height);
  img.loadPixels();
}

function draw(){
  // 描画位置の調整
  translate((width-img.width)/2, (height-img.height)/2);
  // ピクセル位置を取り出す
  let x = floor(random(0, img.width));
  let y = floor(random(0, img.height));
  let pixel_num = (x+y*img.width)*4;
  // 色の取り出し
  let pixel_color = color(0);
   pixel_color.setRed(img.pixels[pixel_num]);
   pixel_color.setGreen(img.pixels[pixel_num+1]);
   pixel_color.setBlue(img.pixels[pixel_num+2]);
   pixel_color.setAlpha(img.pixels[pixel_num+3]);
  // 点の描画
  fill(pixel_color);
  let r = random(1, 15);
  ellipse(x,y,r,r);
}

// 画像を縦横比固定でリサイズ
function resizeImg(img_before,width_after,height_after){
  let scale_rate = min(width_after/img_before.width, height_after/img_before.height);
  let img_width  = floor(img_before.width*scale_rate);
  let img_height = floor(img_before.height*scale_rate);
  img_before.resize(img_width, img_height);
  return img_before
}

function keyPressed(){
  if(key=='s'){
    // 画像を保存(canvasHHMMSS.png)
    let date = new Date();
    saveCanvas('canvas'+('0'+date.getHours()).slice(-2)
                       +('0'+date.getMinutes()).slice(-2)
                       +('0'+date.getSeconds()).slice(-2),'png');
  }
}

これが一応今回の目的だった点描です!

点描
点描(正方形)

上のソースコードではランダムに点を取ってきていますが、これをすべての点で順番にやってみたりするとこんな感じ。

点描(ランダムでない)

失敗作

元のコードを自分なりに理解してコードにしていく過程で、たくさん間違いをしてしまいました。けど、間違いをむしろ活かしていくのがprocessingの凄いところですよね…!

画像のサイズ調整を間違えました(^_^;)

色の指定を間違えました(^_^;)

指定するピクセルを間違えました(^_^;)

雪が降ることもあるようですね(^_^;)

Next Actions

まだ作れていないフィルターがたくさんあるのでそれを作りたい。

このエントリーをはてなブックマークに追加
« »

コメントを残す

メールアドレスが公開されることはありません。

スポンサーリンク

最近のコメント

ブログカテゴリ

スポンサーリンク