ドット絵とか、いいよな
ふと「ドット絵とか、いいよな」という思いに取り憑かれ、写真をドット絵に変換するソフトを作ってみました。
フリーソフトでいいやつないかなと思って探してたのですが、意外にしっくりくるものがないので、仕方なく自分でつくりました。1時間考えながら散歩してたら、なんとなくアルゴリズムが出来上がったので30分くらいで書き上げました。特に苦労したところや工夫したところはないです。
これをInstagramにアップしたら@monestarさんから以下のようなコメント
@karaage0703 かっこいい!これと元写真を多重したい…
— ろんすた@変デジ研究所 (@monestar) 2012年9月23日
早速やってみました。
か、かっこいい!さすが変デジ研究所所長。的確なアドバイスでした。
ソースコード、大したもんじゃないので惜しげ無く公開します。Processingさえダウンロードしてコピペして実行すればすぐできるので。デフォルトのサイズはInstagramに最適化(612×612)されています。
動画にも対応したので、そちらは気が向いたら適当に公開します。
とびだせどうぶつの森のマイデザイン補助ツールに応用
なんとこのプログラムが「どうぶつの森」のマイデザイン補助ツールとして使えると言うことで急遽専用のツールを作成いたしました。以下参照下さい。
ドット絵にするプログラム
実行したら、画像を選ぶだけでドット絵が生成されます。画像保存したいときは「p」ボタン。「d」ボタン押すと元絵との多重露光します。もう一回「d」押すと元に戻ります。ドットを増やしたいときはsize_x, size_y、ドットの枠野太さをかえたいときはdotframe, ドットの大きさを変えたいときはscaleの数字を変えてね。size_x, size_yの比率は選択する画像の比率に合わせるとよいです。
PImage img0; PImage writeImg; //dot parameters int size_x = 51; int size_y = 51; int dotframe = 1; int scale = 12; boolean dxp = false; void setup() { size(size_x*scale, size_y*scale); println("select under exposed photo."); String imgPath = selectInput(); img0 = loadImage(imgPath); writeImg = createGraphics(size_x*scale, size_y*scale, P2D); } void draw(){ 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; // makeing 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(); //dxp if(dxp == true){ background(writeImg); image(img0, 0, 0, width, height); blend(writeImg, 0, 0, width, height, 0 ,0, width, height, SCREEN); }else{ image(writeImg, 0, 0, width, height); } } void keyPressed() { // save image if(key == 'p' || key == 'P') { save("screenshot.jpg"); println("screen saved."); } if(key == 'd' || key == 'D'){ if(dxp == true){ dxp = false; }else{ dxp = true; } } // exit if(key == ' ') { exit(); } }