Blog

メイリオ

実はメイリオまだ進化中! 誕生秘話を河野氏に聞いた - @IT

たくさんはてブされてる記事なので読んだ人も多いかもしれませんがこれは熟読すべき!
河野氏は熱い人だなぁ。一文字へのこだわりがすごい。
Wikipediaの項目もなんだか熱い気がする。。(メイリオ – Wikipedia)

社内プレゼンで使うフォントはメイリオにしよう。
あと、Windows 7には Meiryo UI が入っているので要確認。

・関連記事
XPでも「メイリオ」が正式利用可能に

 

libevent

libeventを使ったhello, world的な小さなプログラム。
(libeventはmemcachedやThriftなどでも利用されているイベント通知API)

・ファイルが更新されたら内容を表示する

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <event.h>

#define BUF 256

void callback(int fd, short event, void* arg);

int main(int argc, char** argv) {
	int fd;
	struct event ev;
	if((fd = open(argv[1], O_RDONLY)) == -1) {
		perror("open");
		return -1;
	}
	event_init();
	event_set(&ev, fd, EV_READ | EV_PERSIST, callback, &ev);
	event_add(&ev, NULL);
	event_dispatch();
	return 0;
}

void callback(int fd, short event, void* arg) {
	char buf[BUF];
	int len;
	//  event_add((struct event*)arg, NULL);
	if((len = read(fd, buf, sizeof(buf) - 1)) == -1) {
		perror("read");
		return;
	}
	buf[len] = '\0';
	printf("%s", buf);
}

event_set 関数で EV_PERSIST を指定すると、イベント通知を継続して受け取ります。
これを指定しない場合は、コールバック関数内で再度 event_add 関数を呼び出す必要があります。
また、登録したイベントを削除したい場合は event_del 関数を利用します。

・参考
libevent + 使い方 | NINXIT-BLOG

 

welcome 2010

新年あけましておめでとうございます。
今年も思いっきり走り抜けたいと思います!

Webエンジニアとしても学びたいことはたくさん。
今年の目標としては、

KVS(Key-Value Store)について深く学ぶ
モダンPerlなコードを書く
システム運用(トラフィックの監視、負荷分散など)を学ぶ

一つめはKey-Value Store。
僕が一番最初に担当した案件からKVSを利用したメディア配信系のシステムだったりして、
全社的にNoSQLへの流れが強くなっています。
業界全体としても大規模なWebアプリケーションを開発するには必要不可欠な技術なので、
これは最優先で取り組むべき課題としたいです。

二つめはPerl。
弊社のサービスフロントエンドの多くはPHPで構築されるようになりましたが、
新規開発案件でPerlが採用されるケースも多いです(Rubyはまだ残念ながら、、)。
僕は会社に入るまでPerlをまともに触ったことがなかったので、一からの勉強に苦労しました。
Perlのモジュールを速く丁寧に書けるようになりたいと思い二つめの目標に。

三つ目はシステム運用。
インフラ寄りの部署に所属しているので、システム運用の業務も行います。
ある程度人のいる会社では開発と運用の分離をしていて、開発担当が運用業務を行うことはあまりないかもしれません。
ただ、こういった分野は大規模な設備で実務を通して学ばないとあまり身に付かないので、
この部署にいる内に一生懸命勉強しておきたいと思います。

あと、もちろんFlashも。
ASはともかくライブラリ/フレームワークには疎くなってしまったので、
そういった制作寄りの情報も追いかけつつ、Webサイト作りなどもやっていきたいと思います。

2010年もよろしくおねがいします。

 

2009年の振り返り

同期のブログもみんな振り返りをやってるので僕も今年1年を簡単に振り返ってみます。

——

大学院修了

無事に大学院を修了する。M1の時は正直まったく研究をしておらず、TAとかパン屋のバイトでお金を稼ぐ日々だったが、M2になってからは姿勢を改めて真面目に研究をしていた。学部生向けに画像処理の基礎をwikiにまとめたり、みんなが好きな環境で研究(開発)できるように環境整備したりと雑務もそれなりに忙しかったが、研究室の良い後輩達に恵まれて充実していたと思う。

就職

Web業界に身を投じる。”組織”と”Webビジネス”を学んでいる中で、コンテンツの”価値”と”権利”について深く考えさせられた。”技術”で解決できる問題ならどんなに楽だろう、とエンジニアは口を揃えてそう言う。同じような経験(勉強)ができる企業はそう多くはないと思うので、これからもしっかり勉強していきたい。もちろん技術的にも新人の間は勉強することばかりで、社内セミナーや同期に教えてもらった勉強会などに参加していろんな技術を勉強した。インフラ寄りの部署に配属され、そこで学ぶこと全てが新鮮で楽しかった。そう思うと同時に、今までやったきた事がいかに表面的で浅い内容だったのかを思い知らされて少しヘコんだ。

——
今年はインプットがメインだったので、来年は会社で学んだことを活かしてアウトプットに変えていきたいです。
2010年もよろしくおねがいします。

 

HTML5でConvolutionFilter

HTML5のcanvasを使って簡単な画像処理をやってみます。
試してみたのは基本的な畳み込みフィルタ。
今回はAS3のConvolutionFilter風のインタフェースで作りました。

Demo: HTML5 Image Processing (Firefox3.5とSafari4で動作確認しています)

汎用的に作ろうとすると少し時間がかかりそうだったので、ひとまず畳み込みフィルタの部分だけ。
引数はAS3のものよりずっと少なく、matrix, divisor, bias の3つ。
matrixXやmatrixYも用意してないのでフィルタカーネルのサイズは3×3限定だし、
異常系の処理も不十分で修正が必要ですが;;
他のフィルタ類は時間を見つけて作ってみようと思います。

・クライアント例

var context = document.getElementById('Canvas').getContext('2d');
var bmp = new Bitmap('sample.jpg', context);
var matrix = [-1, -1, -1,  -1,  8, -1,  -1, -1, -1]; // フィルタカーネル
var divisor = 1;
var bias = 0;
bmp.applyFilter(new ConvolutionFilter(matrix, divisor, bias));

bitmap.js (以下そのままコピペ)

  var Bitmap =  function(source, context) {
    this.initialize.apply(this, arguments);
  };

  var ConvolutionFilter = function(matrix, divisor, bias) {
    this.initialize.apply(this, arguments);
  };

  // TODO: (initialize, apply)
  var BlurFilter = function(blurX, blurY, quality) {
    this.initialize.apply(this, arguments);
  };

  var GlowFilter = function(alpha, blurX, blurY, color, inner, knockout, quality, strength) {
    this.initialize.apply(this, arguments);
  };

  var ColorMatrixFilter = function(matrix) {
    this.initialize.apply(this, arguments);
  };

  Bitmap.prototype = {
    initialize : function(source, context) {
      this.bitmapData = new Image();
      this.bitmapData.src = source;
      this.width = this.bitmapData.width;
      this.height = this.bitmapData.height;
      this.context = context;
      this.bitmapData.addEventListener('error', function() { alert("can't load image"); }, false);
    },
    applyFilter : function(filter) {
      try {
        this.context.drawImage(this.bitmapData, 0, 0);
        var src = this.context.getImageData(0, 0, this.width, this.height);
        var dst = this.context.createImageData(this.width, this.height);
        //var gray = context.createImageData(this.width, this.height);
        filter.apply(src, dst);
        this.context.putImageData(dst, 0, 0);
      }catch(e) {
        alert(e);
      }
    }
  };

  ConvolutionFilter.prototype = {
    initialize : function(matrix, divisor, bias) {
      this.matrix = matrix;
      this.divisor = divisor;
      this.bias = bias;
    },
    apply : function(src, dst) {
      var w = src.width, h = src.height;
      var srcData = src.data;
      var dstData = dst.data;

      //this.cvtColor.apply(this, [src, dst, 'gray']);

      for(var y=1;y<h-1;++y) {
        for(var x=1;x<w-1;++x) {
          var idx = 0;
          var r = 0, g = 0, b = 0;
          //var d = 0;
          var i = (y*w + x) << 2;
          for(var ky=-1;ky<=1;++ky) {
            for(var kx=-1;kx<=1;++kx) {
              var pos = (ky*w << 2) + (kx << 2);
              r += srcData[i + pos]*this.matrix[idx];
              g += srcData[i + pos + 1]*this.matrix[idx];
              b += srcData[i + pos + 2]*this.matrix[idx];
              //d += srcData[i + pos]*this.matrix[idx++];
              idx++;
            }
          }
          dstData[i] = r/this.divisor + this.bias;
          dstData[i + 1] = g/this.divisor + this.bias;
          dstData[i + 2] = b/this.divisor + this.bias;
          dstData[i + 3] = 255;
        }
      }
      // for Firefox
      dstData.forEach(function(n, i, arr) { arr[i] = n<0 ? 0 : n>255 ? 255 : n; });
    },
    cvtColor : function(src, dst, mode) {
      var w = src.width, h = src.height;
      var srcData = src.data;
      var dstData = dst.data;
      switch(mode) {
      case "gray":
        for(var y=0;y<h;y++) {
          for(var x=0;x<w;x++) {
            var i = (y*w + x) << 2;
            dstData[i] = (77*srcData[i] + 150*srcData[i + 1] + 29*srcData[i + 2]) >> 8;
            dstData[i + 1] = dstData[i];
            dstData[i + 2] = dstData[i];
            dstData[i + 3] = 255;
          }
        }
        break;
      case "hsv":
        // TODO
        break;
      case "lab":
        // TODO
        break;
      default:
        break;
      }
    }
  };

ポイントを絞って簡単に説明を。
(以下 context は getContext(‘2d’) で取得したオブジェクト)

* imagedata = context.createImageData(sw, sh)
幅sw, 高さshのImageDataオブジェクトを生成します。
ピクセルデータ(imageData.data)はすべて0(黒)になっています。

* imageData = context.getImageData(sx, sy, sw, sh)
(x, y)=(sx, sy) を基準に幅sw, 高さshの領域のピクセルデータを取得できます(imageData.data)。
これはAS3における BitmapData.getPixels() のようなもので、ARGB32bitのデータを扱い、
インデックスは 0~幅×高さ×4-1 まで。

* context.putImageData(imagedata, dx, dy)
指定されたImageDataオブジェクトを (x, y)=(dx, dy) を基準に描画します。

・参考記事
createImageData, getImageData, putImageData メソッド – Canvasリファレンス – HTML5.JP
・関連記事
HTML5の勉強

 

FITC Tokyo 2009 参加レポート

FITC Tokyo 2009 に参加してきました。
DSC00871

どのセッションも聞き応えがあり良い刺激になりました。

個人的にはNVIDIAさんの話を興味深く聞かせていただきました。
ランチをゆっくり食べ過ぎたせいで途中からしか聞けませんでしたが、内容としては

  • Tegra用に最適化されたFlash Playerでは、H.264ビデオの再生などを行うときにTegraのアクセラレーション機能を利用でき、しかも省電力!
  • OpenGL ES関連 (企業ブースではARのシューティングゲームを展示してた)

OpenCL(とCUDA)関連のことで聞きたいこともあったのですが、ブースはすごい人だかりだったので断念。。
ノベルティとしてもらった携帯液晶クリーナーの厚紙に載っているTegraモジュールの写真も必見です。
ただ、セッションの時間がたった30分しかなくて残念でした。
それにあのデモはもっと大きなどよめきが起こってもいいレベルだと思ったんですが;;

他に興味を持ったのは、Lee BrimelowさんのAIR2.0に関することについて。
ネイティブプロセスの制御や、ネットワーク関連API(DNS周り等)の強化には可能性を感じました。
僕はAIRをほとんど触ったことがないのですが、これを機に時間を作って勉強しようと思います。

セッション終了後のパーティーは、場所を汐留シティセンタービル42Fに移して行われ、
大変景色の良い場所で楽しく過ごすことができました。

他の方々と交流を取らないとご飯が食べられない仕様になっていたので、
Web業界はきびしいなーと友人と一緒に半泣き半笑いで途方にくれているところを
いろんな方々が声をかけてくださったおかげでたくさん食べることができました。
しかもその後のクイズにも正解して分厚いステーキもいただきました。Happy!

もちろん豪華なスピーカーの方々もパーティーに参加されていました。
そこでは(セッションでASの最適化話をされていた)Grant Skinnerさんに
プログラミングを楽しむコツを聞いてみたんですが、
「Workとしてじゃなく、Artとしてプログラミングするといいよ !」
と言われ気付かされました。
技術は芸術。精進します。

パーティーでの反省点としては、名刺とデジカメを持っていかなかったこと。
名刺はもらいっぱなしでほんと申し訳なかったです。学生?とか聞かれたし。。
42Fからの夜景やみなさんの楽しむ姿を写真にも収めたかった。
でも多くの方と交流を持てて大きな活力になりました。
またこのようなイベントがあったときは是非参加したいと思っています。

 

HTML5の勉強

html5_canvas
HTML5::canvas test
(Firefox3.5, Safari4でのみ動作確認しています)

先日の社内コンペでHTML5を使ったすごいデモを出してきたチームがあったので、
僕もそれに刺激を受けていろいろ調べています。
以前Flashで作ったものをHTML5のcanvas要素を使って作り直したりしながら勉強。
簡単な画像処理なんかもできそうなので引き続き調べていきたいと思います。

 

10月おわり

最近は天気のいい日が多いので、お昼休憩は外に出ています。
同期や先輩達と食べるのはいいんですが、週1,2くらいはひとりまったりと過ごす時間を作ろうかと。

Read the rest of this entry »