2010/12/14

JavaScriptでミステリーサークルのようなものを自動生成

フラクタル図形等を作成する際によく用いられる形式文法L-Systemを使って、ミステリーサークルのようなものを自動で生成するものをつくりました。これにより、なんかの儀式にミステリーサークル的な模様が必要になった時に簡単に模様をつくることができます。でも、自分で念を込めて模様を考えたほうが、儀式はうまくいくと思います。

例えばこんな感じの模様ができます。

 

デモ
Key :






なにをしているのか
以下のようなL-Systemを構成し、JavaScriptでCanvasに描画しています。詳しくはソースコードを御覧ください。
Grammer
  Variables : 0
  Constants : [1-9][a-f]
  Start : 0
  Rule : 0 -> md5hash
  Iterate count : 3
ここでmd5hashというのはテキストエリアに入力された文字列のMD5Hash値です。
Semantics
  0 : なにもしない
  d=[1-9] : 左に d x 10 度回転
  a : 50前に直線を描いて進む
  b : 回れ右する
  c : 半径50の円を描く
  d : 原点に戻る
  e : 32前にジャンプする
  f : 半径32の円を描く


余談
テキストエリアに入力された値が同じであれば、同じ模様が出力されます。なにか面白い模様ができたらぜひKeyをコメントしてください!
MD5Hashの計算にはサイボウズ・ラボの光成茂雄さんのライブラリを使用させていただきました。ありがとうございます。

参考
Canvasに色々描いてみた - Webと文字

2010/12/01

Webサイトのサムネイルを撮ってBase64で返すWebサービスつくりました

サーバーサイドでのWebページレンダリングについて調べていたらいつの間にかつくっていました。Base64形式でサムネイルを出力してくれるものは今のところ見当たらなかったので、便利かな。

こちらです!
※負荷がかかった場合にうまくリクエストを捌けないバグがあり、うまく動いていないかもしれません。申し訳ないです。対策中です。

こんな感じのものが撮れます。



使い方
URLをテキストボックスに入力して、Sendボタンを押してしばらく待つと、テキストエリアに何か出力されます。エラーメッセージっぽい場合は無視してください。正しそうならテキストエリアをまるごとコピーしてHPなりブログなりに貼り付けると、うまく画像が表示されるはずです。

内部仕様
使用しているブラウザ : Firefox4 beta7 (en)
フラッシュプラグイン   : Adobe Flash Player 10.2 beta

どんなことをしているか
Xvfbで仮想フレームバッファをつくり、その上でFirefoxを動かし、スクリーンショットを撮って適当に加工してサムネイル化しています。

似たようなサービス
SimpleAPI
IgWebCap
Mozshot
websnaper
2010/12/01現在、僕が試したところ、上記のサービスはあまりうまく機能していませんでした。多分リクエストが多くて負荷が高いのでしょう。
それに加えhttpsに対応していなかったり複雑なURLを送信すると、思ったとおりの結果が得られません。
上記のサービスはサーバー側で画像を一定期間保存するため、サーバーの容量への負担が大きく、また貼りつけ先からのGETリクエストにも答えなければなりません。
拙作のモノはBase64で出力するので、サーバー側で画像を貯めておく必要はありません。

余談
実はこのサービスはNode.jsでのCanvas共有アプリに、書いた絵を保存する機能を付けることを目的にしてできた副産物です。現在のCanvas共有はクライアントから送られてきたデータをそのままサーバーに保存するため、任意のpng画像がサーバーに送り込まれてしまう脆弱性が存在します。事実、公開初日に何者かによりイーノックさんの画像が送り込まれてしまいました。その脆弱性を解消するべく考案したのが、サーバーサイドでのHTMLレンダリング、というわけです。そいういわけでブラウザにはWebSocketおよびWebWorkersに対応したFirefox4betaを選びました。

ご本尊はhttp://etsukata.com/web2img/w2i.plであり、それにたいしてXHRでリクエストをおくっています。サーバーの処理能力に余裕があったらレスポンスヘッダにAccess-Control-Allow-Origin: * を追加してみなさんに使ってもらえるようにしたいと思っています。


参考
pomo123の日記
http://d.hatena.ne.jp/pomo123/20080430/1209532590
The "data" URL scheme - RFC 2397
http://tools.ietf.org/html/rfc2397

2010/11/26

Node.js Canvas共有に絵を保存するGallery機能追加しました

Canvas共有サーバーが機能しているかどうか、よくチェックしているのですが、たまに
「すごい!」
「wonderful!」
「ちょっとカクカクするけどすごい!感動!」
といったメッセージが書きこまれていることがありました。
こういうのを見ると、嬉しくなります!
それに加え、折角書いてもらった絵が保存されずに消されるのは勿体無いことだと感じたので、絵を保存する機能を付け加えました。

YkitamotoさんにcanvasのtoDataURLというメソッドを教えていただいたので、それを利用することにしました。クライアントがClearボタンを押すと、canvasのデータがbase64形式でエンコードされてサーバーに届きます。サーバーはそれをデコードして保存します。
消そうと思ったら保存されてしまうのです。消しゴムは今のところ意図的に付けていません。

デモ
こちらです。どんどん書いてください!
Galleryはこちら。WebSocketに対応していないブラウザでもGalleryは見れます。


参考文献
toDataURL() - WHATWG

2010/11/17

WebWorkersを使ってJavaScript並列素数計算

Web Workersはページ内でバックグラウンドで並列にスクリプトを実行するための機能です。メッセージパッシングでスレッドのような操作ができます。これを用いることにより、例えばJavaScriptで非常に時間のかかる処理をする際、ブラウザが固まってしまう状況を避けることができます。
今回はWeb Workersを使って並列に素数を数えてみようと思います。

以下のデモでは 1000000000001から 1000000001000までの素数を、子Workerを4つ生成し、それらに仕事を等分して分け与えて計算させています。( ) 内は子WorkerのIDです。
申し訳ありませんが、今のところFirefoxのみでしか動きません。ChromeやSafariではWorker内でWorkerオブジェクトにアクセス出来ないのです。

デモ
http://etsukata.com/js/ww.html


Souce code
ww.js
worker.js

Web Workersを触ってみて、これは「ミニErlangだ」と感じました。Erlang程自由にWorker間でメッセージを自由にやりとり出来ないものの、非同期メッセージパッシングというパラダイムは共通です。
Web Workersは単に「ブラウザが固まらないようにバックグラウンドで処理するだけのもの」ではありません。将来的にはJavaScriptでのマルチコアプログラミングや分散コンピューティングに使われるのでないかと予想しています。だいぶ先(5年以上)のことと思いますが。もしかすると、現在ErlangがやっていることがWeb Workersを用いてJavaScriptで記述されるようになる日が来るかもしれません。未来的超高水準言語JavaScriptがErlangすら内包するかも、と嘯いてみます。

nodejs.orgにありがたいお言葉を見つけましたので以下に転載します。
The fundamentals of scalable systems are fast networking and non-blocking design—the rest is message passing. In future versions, Node will be able to fork new processes (using the Web Workers API ) which fits well into the current design.


仕様が定まっておらず、実装が錯綜しているので今のところはなんとも言えない感触です。

追記
Chromeがsubworkerをつくることが出来ない問題についてhidekiyさんにより情報頂きました。いつもお世話になります。Chromiumにissueが出ています。
http://code.google.com/p/chromium/issues/detail?id=50432

参考文献
Web Workers specification - WHATWG
http://www.whatwg.org/specs/web-workers/current-work/
The Basics of Web Workers - HTML5Rocks
Using web workers - MDC
https://developer.mozilla.org/En/Using_web_workers

2010/11/12

Erlang + Websocket でCanvas共有

拙作のerlang_websocket_serverを用いて、Canvas共有をErlangに移植しました。
非同期メッセージパッシングというパラダイムのおかげで簡単に書けます。

こちらです!どんどん落書きしてください!
http://etsukata.com/erl/cvws.html
ChromeおよびSafariで動作確認しています。複数のウインドウを立ち上げて描いてみてください。

クライアントサイドのコードはNode.js版と全く一緒です。
サーバーサイドのコードを以下に掲載します。

githubでお読みになると、横スクロールがなくて見やすいです。
https://github.com/Etsukata/erlang_websocket_server/blob/master/example/canvas_sharing_handler.erl

-module(canvas_sharing_handler).
-import(websocket_server, [unicast/2, broadcast/2, sendall/1]).
-compile(export_all).

go() -> websocket_server:start("etsukata.com", 9000, ?MODULE, canvas_sharing_handler, [[],[]]).

canvas_sharing_handler(IDList, PointList) ->
  receive
    {open, ConnectionID} ->
      broadcast("@NC:" ++ ConnectionID, ConnectionID),
      unicast("@ID:" ++ ConnectionID, ConnectionID),
      StrIDList = lists:foldr(fun(X, Xs) -> X ++ "," ++ Xs end, "", IDList),
      Str = case StrIDList of
              []   -> [];
              _Any -> lists:sublist(StrIDList, length(StrIDList) -1)
            end,
      unicast("@PT:" ++ Str, ConnectionID),
      lists:foreach(fun(X) -> unicast(X, ConnectionID) end, lists:reverse(PointList)),
      canvas_sharing_handler([ConnectionID|IDList], PointList);
    {message, Data, ConnectionID} ->
      case lists:member($@, Data) of
        true ->
          case string:substr(Data, 1, 3) of
            "@CU" ->
              broadcast(Data, ConnectionID),
              canvas_sharing_handler(IDList, []);
            _Any ->
              canvas_sharing_handler(IDList, PointList)
          end;
        false ->
          broadcast(Data, ConnectionID),
          canvas_sharing_handler(IDList, [Data|PointList])
      end;
    {closed, ConnectionID} ->
      broadcast("@CL:" ++ ConnectionID, ConnectionID),
      canvas_sharing_handler(lists:delete(ConnectionID,IDList), PointList);
    Any ->
      io:format("Any:~w~n", [Any]),    
      canvas_sharing_handler(IDList, PointList)
  end.
Node.js版のソースコードとほとんど長さは変わっていません。
Node.jsのスピード感のある開発も楽しいです。しかしErlangのメッセージパッシングで考えたほうがほうが単純に物事を捉えることができ、これもまた楽しいのです。僕はNode.jsとErlang、どっちも好きです!

2010/11/11

ErlangでWebSocket Server実装を書きました

こちらで公開しています
https://github.com/Etsukata/erlang_websocket_server
この記事はGithubに公開している情報を日本語で若干加筆して提供いたします。


動機
以前Node.jsのWebSocket Server実装であるnode-websocket-serverを用いてCanvas共有アプリをつくりました。そのとき手軽でスピード感のある開発に快感を覚えたので、ネットワークとの親和性のが非常に高く、今注目を集めているErlangではできないものかと思い、作りました。
Dave Bryson氏による実装であるerlang_websocketを主に参考にさせて頂きました。氏の実装では一対一の相互通信を行うものであったので、それを拡張し、特定のクライアントにデータを送信したり、マルチキャストしたりできるようにしました。
なにより、node-websocket-serverのように手軽にWebSocketを用いたアプリをつくれるようにするのが目的です。

Process Design Pattern
Erlangでシステムを構築するときはどのようなProcess Design Patternを採用するかが鍵になります。当ライブラリでは以下のような構造になっています。



Socket Receiverがクライアントからデータを受け取り、順々に右のプロセスに渡していきます。ReceiverはWebSocket Frameから生のデータを取り出しHandlerに渡します。Handlerはそれを加工しSenderに渡します。SenderはWebSocket Frameをつくり、各クライアントとつながっているSocket Senderに対しユニキャストまたはマルチキャストでデータを配信します。Socket Senderは受け取ったものをクライアントに送信します。
と、いった感じです。
ユーザーはHandlerの振る舞いについてのみ記述すればいいようになっています。

サンプル
エコーサーバーを書く場合は以下で十分です。

-module(echo_handler).
-compile(export_all).
-import(websocket_server, [unicast/2]).
go() ->
   websocket_server:start("localhost", 9000, ?MODULE, default_echo_handler, []).
default_echo_handler() ->
  receive
    {message, Data, ConnectionID} ->
      unicast(Data, ConnectionID),
      default_echo_handler();
    _Any -> default_echo_handler()
  end.

ドキュメント
こちらにあります。
http://etsukata.com/erl/docs/


今後
これからはどのような機能を盛りこんでいくかを決めるために、いくつかこのライブラリを用いたWebSocketアプリをつくっていくつもりです。経験を積んで、何が必要で重要なのか、何が要らない物なのかを見定めたいと思っています。

参考URL
Comet is dead long live websockets
http://armstrongonsoftware.blogspot.com/2009/12/comet-is-dead-long-live-websockets.html
davebryson / erlang_websocket
https://github.com/davebryson/erlang_websocket
MiCHiLU / erlang_websocket
https://github.com/MiCHiLU/erlang_websocket

2010/11/07

[Node.js] How to handle ECONNRESET, Connection reset by peer and automatic crashing.

Error Message
node.js:63
    throw e;
    ^
Error: ECONNRESET, Connection reset by peer
    at Stream._readImpl (net:304:14)
    at IOWatcher.callback (net:454:24)
    at node.js:768:9

The error 'ECONNRESET, Connection reset by peer' like the above is thrown when a connection was forcibly closed by peer. For example, a sudden lost of connection due to unstable network environment or unexpected crash of a browser, etc. 
If such exception bubbles all the way back to event loop, the node process print a stack trace and exit as the default action. Try/catch blocks can't catch the excption which occurs in event loop.
To prevent these errors from crashing down your node server, please use

process.on('uncaughtException', function (err) {
  // handle the error
});

Reference
[nodejs.org] Event: 'uncautException'
[nodejs@googlegroups.com] How to prevent node from dying on error?
[technet.microsoft.com] Connection reset by peer

Node.js + Websocket Canvas共有システムが時折ダウンする問題について

2010/10/27にCanvas共有Websocketサーバーを作動させて以来、サーバーがのべ三度にわたりダウンするという問題が発生していました。原因の究明を進めていたところ、一部ダウンする状況の再現及び対処法を突き止めましたのでご報告申し上げます。なお、ダウン中にアクセスされ、Canvas共有を体験なさることが出来なかった読者の方々には深くお詫び申し上げます。これからもダウンの折には早急な原因の解明と対処に努めますので、どうか今後ともよろしくお願いいたします。

サーバーダウン時のエラー出力の内容
node.js:63
    throw e;
    ^
Error: ECONNRESET, Connection reset by peer
    at Stream._readImpl (net:304:14)
    at IOWatcher.callback (net:454:24)
    at node.js:768:9

原因
Node.jsでは発生した例外がイベントループまで到達した場合、デフォルトの動作として、スタックトレースを出力し、終了することになっています。上記の例外が発生した場合、サーバーはダウンします。なお、スタックトレースをご覧いただければわかりますとおり、例外がイベントループ内において発生していますので try/catchで捕まえることはできません。
問題は、どのような状況において上記の例外が発生するか、ということです。
上記の例外は時折にしか発生せず、原因がなにかわからなかったのですが、ようやく突き止めました。Websocketクライアントが正常に接続を終了しない場合に発生していたのです。試しにサーバーへのコネクションを張ったまま、LANケーブルを引っこ抜いてみると、まんまと上記の例外が出ました。おそらくは不安定なネットワーク環境のもとCanvas共有にアクセスし、途中でネットワークが切断された際やブラウザがクラッシュした際等に発生していたのでしょう。

対策
例外発生時の動作をデフォルトのものから変更します。
参照:Event: 'uncaughtException'

ちなみに「Connection reset by peer node.js」で検索したところ、同じ問題で困っていた仲間が大量にいました。


Node.jsで何か作る際には、あらかじめ例外発生時の動作を適切なものに設定なさることをおすすめします。デフォルトだとプロセスは終了してしまいます。
ただ、なんでもprocess.on('uncaughtException')を使って何事もなかったかのようにサーバーを動かし続けることには注意が必要な場合があります。以下を御覧ください。
node.js - Dealing with uncaught exceptions
http://debuggable.com/posts/node-js-dealing-with-uncaught-exceptions:4c933d54-1428-443c-928d-4e1ecbdd56cb

2010/10/27

Node.js + Websocket でCanvas共有

友人のhidekiyさんにNode.jsというこれから流行りそうなおもちゃを紹介してもらったので遊ぼうと思います。
Node.jsはV8 JavaScriptエンジン上でイベント化された入出力を扱うフレームワークです。
Node.jsを用いて簡単な落書き板のようなものをつくりました。Websocketサーバーに接続して、みんなでリアルタイムにCanvasを共有し、書き込むことができます。接続時に、サーバーに落書きデータがある場合はそれをダウンロードしてクライアントのCanvasに書き加えます。
クライアントサイドもサーバーサイドもJavaScriptで書けるって、やっぱり気持ちいいです。

対応ブラウザはSafariとChromeです。
Port:8888 をWebsocketの通信に使用しています。ウイルス対策ソフトのブロッキングやプロキシ環境下においては通信できない可能性がありますのでご注意ください。

ぜひ、落書きしてみてください!
http://etsukata.com/node/cvws.html
↑これです

Sorce codeはサーバーサイド、クライアントサイド共にこちらでご覧いただけます。
http://etsukata.com/node/
サーバーサイド    : cvwsserver.js
クライアントサイド : cvwsclient.js





参考URL:
Node.js
http://nodejs.org/
websocket-server
http://github.com/miksago/node-websocket-server


2010/10/19

Ajaxでフラクタルを描画 with Google App Engine

Google App Engineを用いてマンデルブロ集合を描画してみました。
目的はpure JavaScriptで時間のかかる処理をGAEにまかせてしまえば高速に描画できるのではないかと思ったからです。GoogleMapみたいにフラクタル世界をスイスイしたかったのです。

処理内容
1.サーバーサイドで各点の発散を調べ、ループ回数を返します。
2.クライアントサイドでCanvasに色付けします。

問題点
自分の環境だと残念ながらscaleがある程度大きくない限り、ほぼ似たような処理時間になってしまいました。Canvasへのピクセル操作に時間がかかってしまうのです。

JSONのパースに時間がかかるのかと思い、ランレングス圧縮したシリアライズ方式でもやってみましたが、同様の時間がかかてしましました。Canvasのピクセル操作がネックになっているのでどうしようもないんでしょうか...?救いは無いんですか?
ランレングスパック前 http://mandelbrot-fractal.appspot.com/mandelbrot?centerx=0&centery=0&scale=1&pack=0
ランレングスパック後 http://mandelbrot-fractal.appspot.com/mandelbrot?centerx=0&centery=0&scale=1&pack=1

折角AjaxにしたんならGoogle Mapみたいにドラッグや拡大などできるようにするべきですが、ラグが大きいので諦めてしまいました。

ちなみに"Access-Control-Allow-Origin: *"をHTTP Responseに加えてあるので、Same Origin Policyを満たさなくてもどなたでもご自由にお使いいただけます。サーバーサイドはJavaで書きました。

Fractal with Google App Engine
http://mandelbrot-fractal.appspot.com/

追記(2010/11/10)
コメントしてくださったYkitamotoさんの指摘を元に、ピクセル操作を改善したところ、かなり速くなりました!デモまでつくって教えてくださったYkitamotoさん、ありがとうございます!下記の実行時間比較も書き直しました。



実行時間(ms)比較(パラメーター:Center x = -1.1, Center y = 0, Scale = 10)


GAE PureJS
Google Chrome7 681 1787
Safari5 753 923
FireFox3.6 732 231

IE8とOpera10.63には未対応です。


Ajax with GAE Demo



Center x :
Center y :
Scale :


Pure JavaScript Demo



Center x :
Center y :
Scale :

参考にさせていただいたページ:
[xhr] XMLHttpRequest Level 2時代のクロスドメインリクエストProxy
http://blog.hidekiy.com/2010/10/xhr-xhr-lv2proxy.html
Ajax - Goodbye, JSONP. Hello, Access-Control-Allow-Origin
http://blog.livedoor.jp/dankogai/archives/51502865.html

2010/10/15

改ざん検知機能付きストリーム暗号運用モードMULTI-S01のJavaScriptによる実装

MULTI-S01は日立製作所システム開発研究所により開発された改ざん検知機能付きストリーム暗号運用モードです。 MULTI-S01は暗号技術評価プロジェクトCRYPTREC作成の「電子政府推奨暗号リスト」ISO/IEC 18033の標準暗号として採用されています。

MULTI-S01をJavaScriptで実装しました。 このライブラリでMULTI-S01の改ざん検知機能付きストリーム暗号運用モードを利用できます。
しかし、仕様書等にテストデータが記載されていないので、正確さは保証できません。


日立製作所 MULTI-S01のページ
http://www.sdl.hitachi.co.jp/crypto/s01/

Demonstration

このデモではストリーム暗号にMUGIを使用しています。 生成した暗号文が改ざんされていると、それを検知してエラーメッセージを出力します。 暗号文を生成し、すこし内容を変えてみてDecryptボタンを押してみてください。
Key in hex(128-bit):
InitialVector in hex(128-bit):
Redundancy in hex(64-bit):
Plain Text:
Encrypted Text:
Decrypted Text:
Source: multi.js



擬似乱数生成器MUGIのJavaScriptによる実装

MUGIは日立製作所システム開発研究所により開発された疑似乱数生成器です。 MUGIは暗号技術評価プロジェクトCRYPTREC作成の「電子政府推奨暗号リスト」ISO/IEC 18033の標準暗号として採用されています。

MUGIをJavaScriptで実装しました。 このライブラリでMUGIの疑似乱数生成機能を利用できます。
しかし、仕様書に記載されているテストデータでしかテストしていないため、正確さは保証できません。

日立製作所システム開発研究所MUGIのページ
http://www.sdl.hitachi.co.jp/crypto/mugi/


Demonstration

Key in hex(128-bit):
InitialVector in hex(128-bit):
Size of output:
GeneratedRandom in hex:


Source: mugi.js

2012/11/6 追記
chk さんのご指摘により、擬似乱数を16進数で表記する処理のバグ修正を施しました。
chk さん、誠にありがとうございます!

Firefox 3.6 (Gecko 1.9.2) MozOrientation サンプル

最近ノートパソコンをThinkPadに買い替えました。
僕の買ったThinkPadSL510にはハードディスク・アクティブプロテクション・システムが搭載されており、加速度センサーを内蔵しています。
折角なのでこのセンサーで遊んでみました。
点の軌跡の接線を適当にグラデーションをつけて描きます。
FireFox3.6+ と 加速度センサーをつけたPC が必要です。
(マウスを載せても描きます。)


count =
x =
y =
z =

こんなふうになります。


参考URL:
window.onmozorientation - MDC
https://developer.mozilla.org/ja/DOM/window.onmozorientation
Detecting device orientation - MDC
https://developer.mozilla.org/en/Detecting_device_orientation


2010/08/31

顔認識WEBAPIを利用したプリクラ風顔写真製造機

以前友達とプリクラを撮ったのですが、その写真の加工の仕方にかなり驚くと同時に興味をもちました。 
どうやらプリクラ機体では顔を認識し、目をデカくしてパッチリさせたり、多少露骨な美白処理を行っているようです。 
そういう処理をWEBでやってみたいと思っていたところ、折よくWEBで顔認識APIを公開しているところがあったので、夏休みの工作がてらつくってみたというわけです。 

2013/3/31 追記:飽きたので停止しました使い方 
syame@mail.etsukata.com 
1.上記のメールアドレスに、顔の写った写真を添付して送る 
2.うまく顔認識できた場合上記のアドレスから、加工した写真が添付されてくる。顔認識できなかった場合はエラーメッセージが返信される。 

※パソコンでも携帯でも大丈夫です。 
※サポートしている写真の形式はjpg, jpeg, png, gifです。 
※写真は一度に何枚添付してもらっても構いません。 
※左目と右目を結んだ線が水平になるように撮ったほうが良いと思います。 
※正面を向いたほうが、顔認識されやすいです。 
exclamation ×2僕に見られるとまずい写真は送信しないほうがいいとおもいます。 

使用したWEBAPI : http://face.com 


技術的な事:


使用している言語はPHPです。理由はface.comにPHP用のライブラリがあったからです。
opencvを利用すればわざわざWEBAPIを利用せずに済むのですが、目や鼻の座標まで特定するのは難しいようです。
他にも顔認識WEBAPIは存在しますが、自分がためした限りでは今現在のところ一番精度が高く、優秀なのはface.comのものであるように思いました。
他の顔認識WEBAPI
http://detectface.com/
http://kaolabo.com/webapi

美白フィルターについてですが、画像全体に対して彩度を下げ明度を上げるという処理をしています。それに加え、顔の中心の座標の色相を抽出し、似た色相のピクセルに対して、より彩度を下げ、明度を上げる処理を加えています。
デカ目フィルターは今のところ適当に目を切り抜いて貼りつけているだけです。
いまのところbeta版のため、美白フィルターがいまいちであったり、目をデカくするのがうまくいかなかったりします。ある友人の顔で試したところ、眉毛を目と認識してしまい、眉毛がデカくなった写真が返ってきてしましました。 

要望や、バグレポート等大歓迎です。 
自分を実験台にした写真を添えておきます。

2010/04/22

業務用ドレッシングの配合について

先日キューピーの業務用ドレッシング(1ℓ)を購入した際、ラベルに
「・この商品は業務用向けに配合されています。」
という文句が記載されていました。
たしかに味が薄いように感じました。気になったので調べてみました。

ネットで調べてみると以下のような回答が見当たりました。
http://recipe.gourmet.yahoo.co.jp/question/detail/1415862634/

上記の情報にはソースがないので、直接キューピーさんに問い合わせることにしました。
以下その回答です。
メールをいただきありがとうございました。
日頃はキユーピー製品をご愛用いただき、重ねてお礼申しあげます。

この度は、「キユーピーシーザーサラダドレッシングの業務用と家庭用の
違い」について、お問合せを頂戴いたしました。

業務用商品と家庭用商品では、商品名が同一でも味の仕立てが異なるもの
が大半となっております。
そのことを明確にするための表示でございます。
具体的には、家庭用が食用植物油脂の配合が多く、濃厚な仕立てであり、
業務用は素材の味を生かすような仕立てとなっております。

なお、配合の詳細につきましては、弊社のノウハウでございますので、
開示は控えさせて頂きます。

以上、簡単ですがお答えとさせて頂きます。
今後とも、よろしくお願い申し上げます。

キユーピー株式会社 お客様相談室
TEL:0120-14-1122
http://www.kewpie.co.jp
とのことです。
濃厚なドレッシングが好い場合は家庭用を買うか、業務用をアレンジするのが良いかもしれません。