TP

Advent Art:北斎の絵を生成する

×

実際の結果を見るにはここをクリック!

ここ数年、日本のF# コミュニティは「F# Advent Calendar」というイベントを開催しています (2010年2011年2012年、 そして 今年)。 これはadvent dayごとに1人ずつ、F#に関連した何かしら興味深い記事を作成するというものです。 私は去年からTwitterでadvent calendarをチェックしていて、 今年からは私も参加しようと思い、記事を書きたいと申し出ました。 そうしたところ、数名の方からの協力を得ることができました。 @igeta には参加手続きの諸々とレビューを、 @yukitos にはこの記事の翻訳を、そして @gab_km には翻訳のレビューをしていただきました。 ありがとう!

けれども何についての記事を書くのがよいのでしょう? 過去一年にわたって、F#コミュニティで開発されているF#のオープンソースライブラリやプロジェクトを いくつか紹介できるような記事がよさそうです。 それと同時に、日本に関連のあるトピックが何かないものでしょうか? 少し考えてみたところ、以下のようなプランを思いつきました:

日本の芸術の探索

Freebase は主にWikipediaを情報源とする 体系的な情報を持ったオンラインのグラフデータベースです。 このデータベースには(政治、芸能などの)社会や(多種多様な)スポーツ、 (コンピュータや化学などの)サイエンス、そして芸術など、様々な分野に関する情報が 含まれています。

F# DataにあるFreebase用のF# 型プロバイダーを使用すると、 コードエディタ上から直接これらの情報すべてにアクセスできます。 この型プロバイダーを使うには、まず FSharp.Data のNuGetパッケージをインストールした後、 以下のようにしてアセンブリへの参照を追加します:

1: 
2: 
3: 
4: 
5: 
#I "../packages/FSharp.Data.1.1.10/lib/net40"
#r "FSharp.Data.dll"

open FSharp.Data
open System.Linq

FSharp.Data とは別に、いくつかLINQメソッドを使ってデータを探索します。 Freebaseへのアクセスには FreebaseData または FreebaseDataProvider を使います。 後者には大量のリクエストを発行するコードを作成する場合に必要になるAPIキーを指定します。 サンプルをきちんと動かすためには、登録を行う必要があるでしょう:

1: 
2: 
type FreebaseData = FreebaseDataProvider<(自分のキーをこの位置に入力すること)>
let fb = FreebaseData.GetDataContext()

そして fb. と入力すると、Freebase上で利用できる各分野が一覧表示されます。 たとえば絵画や画家が含まれている「Visual Art」の分野を参照して、 (「Visual Artists」という)リストから1番目の画家を取得し、 画家に関する情報を調べることができます:

1: 
2: 
3: 
4: 
5: 
let art = fb.``Arts and Entertainment``.``Visual Art``

let ldv = art.``Visual Artists``.First()
ldv.``Country of nationality``
ldv.Artworks

このコードを実行してみると、リストの1番目の画家が レオナルド・ダ・ビンチ(Leonardo da Vinci)であることが確認できるでしょう。 Country of nationality プロパティは実際にはlistを返しますが、 今回の場合は単にイタリア(Italy)という1カ国の名前だけが含まれます。 また、 Artworks プロパティを使うと画家の作品一覧を取得できます。

次に、日本国籍を持った画家一覧を見つけるクエリを作成します (簡単のために、国籍リストの最初の1つだけしかチェックしていません):

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
9: 
// 日本の画家を探すためのクエリ
let artists =
  query { for p in art.``Visual Artists`` do
          where (p.``Country of nationality``.Count() > 0)
          where (p.``Country of nationality``.First().Name = "Japan") }

// 検索された画家全員の名前を表示
for a in artists do 
  printfn "%s (%s)" a.Name a.``Date of birth``

このスニペットを実行すると、Yoshitaka Amano(天野喜孝)やIsamu Noguchi(イサムノグチ)、 Takashi Murakami(村上隆)といった20世紀生まれの画家が最初に表示されます。 sortBysortByDescending を追加して、特定の順序に並び替えることもできます。 また、特定の1人の画家を検索するクエリに head を組み合わせて、1人の画家に関する 詳細情報を取得することもできます:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
// 北斎に関する詳細情報を検索
let hok = 
  query { for p in art.``Visual Artists`` do
          where (p.Name = "Hokusai")
          head }

// 画像のURLや説明文、作品一覧を表示
printfn "<img src=\"%s\" />" hok.MainImage
printfn "<p>%s</p>" (hok.Blurb.First())
for a in hok.Artworks do
  printfn "<h3>%s</h3><img src=\"%s\" />" a.Name a.MainImage

スニペットの後半では北斎の様々な情報をHTML形式で出力しています。 結果は以下のようになります:

Katsushika Hokusai (葛飾 北斎, September 23, 1760 – May 10, 1849) was a Japanese artist, ukiyo-e painter and printmaker of the Edo period. He was influenced by such painters as Sesshu, and other styles of Chinese painting. Born in Edo (now Tokyo), Hokusai is best known as author of the woodblock print series Thirty-six Views of Mount Fuji (富嶽三十六景, Fugaku Sanjūroku-kei, c. 1831) which includes the internationally recognized print, The Great Wave off Kanagawa, created during the 1820s.

The Dream of the Fisherman's Wife
The Great Wave off Kanagawa
Travellers Crossing the Oi River
Red Fuji
Feminine Wave
Masculine Wave
Black Fuji
Oceans of Wisdom

北斎とフラクタル

北斎の作品を見てみると、フラクタルのように見えるものがいくつかあることがわかります。 Hokusai と fractal でGoogle画像検索 してみると、北斎の作品とよく似たフラクタルが多数見つかることがわかります。

この記事ではジュリア集合のフラクタルを使います。 このフラクタルは(特にF#を使用すると)非常に簡単に描画できます。 神奈川沖浪裏(The Great Wave off Kanagawa)によく似たフラクタルになるようにするため、 フラクタルを色づけるためのカラーパレットを慎重に選択することになります。

ジュリア集合の計算

ジュリア集合については Wikipediaのページ に詳しいので、ここでは動作の詳細については説明しません。 大まかにいえば、複素数のシーケンスを生成して、何らかの定数 c に対して 各ステップ毎に cnext = cprev2 + c という式で次の値を計算していきます。 この反復処理は無限のシーケンスを生成する(可能性のある) 再帰的なシーケンス式を書くことでいい具合に作成できます:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
open System.Drawing
open System.Numerics

/// それらしいフラクタルを生成するための定数
let c = Complex(-0.70176, -0.3842)

/// 特定の座標に対するシーケンスを生成する
let iterate x y =
  let rec loop current = seq { 
    yield current
    yield! loop (current ** 2.0 + c) }
  loop (Complex(x, y))

この関数は(-1から+1までの)座標を引数にとり、画面上の1ピクセルに対する シーケンスを生成します。 次に、絶対値が2以上になるまで(あるいは反復回数の最大値が特定の制限値を超えるまで) 反復回数を数える必要があります。 具体的には Seq モジュールの関数を以下のように使います:

1: 
2: 
3: 
4: 
5: 
let countIterations max x y = 
  iterate x y
  |> Seq.take (max - 1)
  |> Seq.takeWhile (fun v -> Complex.Abs(v) < 2.0)
  |> Seq.length

まず、反復回数を特定の値に制限していて、 次に絶対値が小さい値を取得しつづけて、 最後にシーケンスの長さを計算しています。 (絶対値が2.0を超えると takeWhile 関数はシーケンスの生成を終了します。 また、 length の値は max - 1 以下になります。) このコードは命令的な方法でも実装できます。 実際その方がパフォーマンスがいいかもしれません。 しかし今回の方法の方がジュリア集合の定義に則していることがはっきりわかります。

カラーパレットの生成

フラクタルを描画するためには、描画したいすべてのピクセルを走査して、 それぞれのピクセルに対して特定の x および y を引数に指定して countInterations を呼び出し、反復回数に応じた色をパレットから 取得することになります。 北斎の絵画をフラクタルで表現するためには、このパレットを慎重に生成する必要があります。 アイデアとしては神奈川沖浪裏(The Great Wave off Kanagawa)で使われている 多数の色のグラデーションを作成します。

そこで、 clr1 -- count --> clr2 というような記述ができるように 2つのカスタムF#演算子を用意します。 この式は clr1 から clr2 まで、ステップ数 count で グラデーションするような色を表します:

1: 
2: 
3: 
4: 
5: 
6: 
7: 
8: 
// 2つの色を'count'ステップ数でグラデーションする
let (--) clr count = clr, count
let (-->) ((r1,g1,b1), count) (r2,g2,b2) = [
  for c in 0 .. count - 1 ->
    let k = float c / float count
    let mid v1 v2 = 
      int (float v1 + ((float v2) - (float v1)) * k) 
    Color.FromArgb(mid r1 r2, mid g1 g2, mid b1 b2) ]

-- 演算子はタプルを生成する構文的なトリックにすぎません。 式は (clr1 -- count) --> clr2 というように解析されるので、 2番目の演算子は初期色とステップ数を受け取って、 グラデーションを構成する色のリストを生成することができます。

そうすると配列式と yield! を使って、各グラデーションを組み合わせることで うまい具合にパレットを生成することができます。 まず空色から始めて、(水を表す)青系のグラデーションをいくつか生成し、 最後に白系のグラデーションを追加します:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
// 北斎の作品で使われているカラーパレット
let palette = 
  [| // 3つの空の色と、ライトブルーまでのグラデーション
     yield! (245,219,184) --3--> (245,219,184) 
     yield! (245,219,184) --4--> (138,173,179)
     // ダークブルーまでのグラデーションと、ミディアムダークブルーまでのグラデーション
     yield! (138,173,179) --4--> (2,12,74)
     yield! (2,12,74)     --4--> (61,102,130)
     // 波の色までのグラデーションと、ライトブルーまで、そして波の色に戻るまでのグラデーション
     yield! (61,102,130)  -- 8--> (249,243,221) 
     yield! (249,243,221) --32--> (138,173,179) 
     yield! (138,173,179) --32--> (61,102,130) |]

フラクタルの描画

さてこれでフラクタルを描画するためのものがすべて揃いました。 最初のバージョンをシンプルなものにするために、まずはWindowsフォームと System.DrawingBitmap を使うことにしましょう。 フォームを作成するコードについては省略します (ただし GitHub上に完全なソースコード が置いてあります)。

フォームとビットマップを作成した後は、ビットマップの各ピクセルを走査して、 (パレットの長さを最大値として)反復の回数を数えて、 その値をインデックスにしてパレットから色を取得します:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
(PictureBoxを持ったフォームを作成)

// 描画する領域を指定する
let w = -0.4, 0.4
let h = -0.95, -0.35

// フォームのサイズに一致するBitmapを作成する
let width = float f.ClientSize.Width
let height = float f.ClientSize.Height
let bmp = new Bitmap(f.ClientSize.Width, f.ClientSize.Height)

// 各ピクセルに対して、指定の領域になるよう変形した後、
// countInterations とパレットを使って色を選択する
for x in 0 .. bmp.Width - 1 do
  for y in 0 .. bmp.Height - 1 do 
    let x' = (float x / width * (snd w - fst w)) + fst w
    let y' = (float y / height * (snd h - fst h)) + fst h
    let it = countIterations palette.Length x' y' 
    bmp.SetPixel(x, y, palette.[it])
i.Image <- bmp

引数 wh はそれぞれ描画するフラクタルの部分を表すタプルです。 これらの値を -2.0, 2.0-1.5, 1.5 に変更すればフラクタル全体が表示されます。 ここでは以下のような素敵な絵が表示されるように、フラクタルの特別な場所を 選択しています:

Fun(Script)の追加

さてこれでフラクタルを描画するコードが出来上がったわけですが、 Windowsフォームプロジェクトを新しく作成することなしに、 ライブで実行される様子を皆さんも見てみたいのではないかと思います。 幸いにも私たちはF#コードをJavaScriptに変換する FunScript というコンパイラが使えるわけなので、HTML5の <canvas> 要素に フラクタルを描画するようにできます。 FunScriptには既にHTML5でマンデルブロ集合を描画するようなサンプルがあるので、 これもまた実に簡単に実装できます。 ただし重要なのは、これまで作成してきたコードを単に再利用することができる、という点です。 詳細をすべて説明するスペースもないので、重要なリンクをいくつか紹介するにとどめます:

まず描画関数を変更するところから見ていきましょう。 実際にJavaScriptで動作しているバージョンをみてもわかるように、 描画処理がやや遅いため、列を描画する毎に表示している絵を更新しています。 (元々のコードを動的型付けであるJavaScriptへとコピーしているだけなので、 パフォーマンスの低下は想定通りです。 命令的なスタイルに書き直せばコードのパフォーマンスを改善できるでしょう。)

しかし描画関数をF#の async ワークフローでラップして、1列描画が終わる度に Async.Sleep を呼んで絵を更新するようにすればかなりいい感じのコードになります:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
/// 列毎にスリープしつつ、非同期的にフラクタルを描画する
let render () = async {
  // <canvas> 要素を取得して、描画する画像を作成する
  let canv : HTMLCanvasElement = Globals.document?canvas
  let ctx = canv.getContext_2d()
  let img = ctx.createImageData(float width, float height)
    
  // 各ピクセルに対して、特定の領域になるよう変形した後、
  // countInterations とパレットを使って色を選択する
  for x in 0 .. int width - 1 do
    for y in 0 .. int height - 1 do 
      let x' = (float x / width * (snd w - fst w)) + fst w
      let y' = (float y / height * (snd h - fst h)) + fst h
      let it = countIterations palette.Length x' y' 
      setPixel img x y width palette.[it]

    // ノンブロッキングなスリープを追加&フラクタルを更新
    do! Async.Sleep(1)
    ctx.putImageData(img, 0.0, 0.0) }

このコードは先ほどのものとほとんど同じです。 なおFunScriptにはJavaScriptライブラリのほとんどの機能に対する型付きのラッパーがあるため、 コード中の変数はいずれも静的に型付けされます(つまり canvHTMLCanvasElement 型で、 描画コンテキストを取得する getContext_2d メソッドなどを持ちます)。 また、1つのピクセルに色を設定するためのヘルパー関数 setPixel や、 IDによってHTML要素を得るための動的検索演算子 ? を使っています (いずれも次の節で紹介します)。 描画を開始するにはイベントハンドラをセットアップして StartImmediate メソッドを呼び出します:

1: 
2: 
3: 
4: 
// 描画を開始するため、ボタンにイベントハンドラを設定する
let go : HTMLButtonElement = Globals.document?go
go.addEventListener_click(fun _ -> 
  render() |> Async.StartImmediate; null)  

ここで使っている2つのヘルパー関数もかなり単純なものです。 setPixelImageData 配列のオフセットを計算してR,G,Bのコンポーネント (とアルファチャネル)を設定しているだけです。 動的演算子も、 getElementById を呼んで、期待される型に要素をキャストして返しているだけです:

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
/// ImageDataにあるピクセルの値を特定の色に設定する
let setPixel (img:ImageData) x y width (r, g, b) =
  let index = (x + y * int width) * 4
  img.data.[index+0] <- r
  img.data.[index+1] <- g
  img.data.[index+2] <- b
  img.data.[index+3] <- 255.0

/// IDで見つかるHTML要素を返す動的演算子
let (?) (doc:Document) name :'R =  
  doc.getElementById(name) :?> 'R

まとめ

まず最初に、私がこの記事を楽しんで書くことが出来たのと同じように、 皆さんが私の記事を楽しく読むことが出来ていますように。 そしてとても素敵なクリスマスシーズンを皆さんが過ごせていますように!

冒頭でも触れましたが、私はここ最近F#コミュニティで開発されている 興味深いライブラリを紹介したいと思っていて、また日本に関連のあるテーマと 絡めて紹介できたらいいなと思っていました。 最初は F# Data 、 特にFreebase型プロバイダを使って日本の画家とそれぞれの作品のリストを取得しました。

次に北斎を題材にして、適切に選択したパレットを使ったジュリア集合で 彼の作である神奈川沖浪裏の再作成に挑戦しました。 最初のバージョンでは、Windowsフォームを使って描画しました。 Webブラウザ上で直接実行できるコードにするためには、 FunScriptを使ってF#をJavaScriptへと変換しました。 ここでは既存のコードを変更する必要がほとんどありませんでした。 フラクタルの描画進捗を確認できるようにするには、 (ボーナスとして)非同期ワークフローを追加するだけでした。

Multiple items
namespace FSharp

--------------------
namespace Microsoft.FSharp
Multiple items
namespace FSharp.Data

--------------------
namespace Microsoft.FSharp.Data
namespace System
namespace System.Linq
type FreebaseData = FreebaseDataProvider<...>

Full name: Japan-advent-art.FreebaseData
type FreebaseDataProvider

Full name: FSharp.Data.FreebaseDataProvider


<summary>Typed representation of Freebase data with additional configuration parameters</summary>
                    <param name='Key'>The API key for the MQL metadata service (default: none)</param>
                    <param name='ServiceUrl'>The service URL for the MQL metadata service (default: https://www.googleapis.com/freebase/v1)</param>
                    <param name='NumIndividuals'>The maximum number of sample individuals for each Freebase type (default: 1000)</param>
                    <param name='UseUnitsOfMeasure'>Use the unit-of-measure annotations from the data source metadata (default: true)</param>
                    <param name='Pluralize'>Use adhoc rules to pluralize the names of types when forming names of collections (default: true)</param>
                    <param name='SnapshotDate'>Use a snapshot of the web data store at the given date and/or time in ISO8601 format, e.g., 2012-01-18, 2012-09-15T21:11:32. A value of 'now' indicates the compile time of the code. (default: no snapshot)</param>
                    <param name='LocalCache'>Use a persistent local cache for schema requests. Also provides the default for whether a persistent local cache is used at runtime. A per-session cache is always used for schema data but it will not persist if this is set to 'false'. (default: true)</param>
                    <param name='AllowLocalQueryEvaluation'>Allow local evalution of some parts of a query. If false, then an exception will be raised if a query can't be evaluated fully on the server. If true, data sets may be implicitly brought to the client for processing. (default: true)</param>
"AIzaSyCEgJTvxPjj6zqLKTK06nPYkUooSO1tB0w"
val fb : FreebaseDataProvider<...>.ServiceTypes.FreebaseService

Full name: Japan-advent-art.fb
Multiple items
FreebaseDataProvider<...>.GetDataContext() : FreebaseDataProvider<...>.ServiceTypes.FreebaseService

--------------------
FreebaseData.GetDataContext() : FreebaseData.ServiceTypes.FreebaseService
val art : obj

Full name: Japan-advent-art.art
val ldv : obj

Full name: Japan-advent-art.ldv
val artists : IQueryable<obj>

Full name: Japan-advent-art.artists
val query : Linq.QueryBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.query
val p : obj
custom operation: where (bool)

Calls Linq.QueryBuilder.Where
val a : obj
val printfn : format:Printf.TextWriterFormat<'T> -> 'T

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val hok : IQueryable<obj>

Full name: Japan-advent-art.hok
val p : Linq.QuerySource<obj,IQueryable>
custom operation: head

Calls Linq.QueryBuilder.Head
namespace System.Drawing
namespace System.Numerics
val c : Complex

Full name: Japan-advent-art.c


 それらしいフラクタルを生成するための定数
Multiple items
type Complex =
  struct
    new : real:float * imaginary:float -> Complex
    member Equals : obj:obj -> bool + 1 overload
    member GetHashCode : unit -> int
    member Imaginary : float
    member Magnitude : float
    member Phase : float
    member Real : float
    member ToString : unit -> string + 3 overloads
    static val Zero : Complex
    static val One : Complex
    ...
  end

Full name: System.Numerics.Complex

--------------------
Complex()
Complex(real: float, imaginary: float) : unit
val iterate : x:float -> y:float -> seq<Complex>

Full name: Japan-advent-art.iterate


 特定の座標に対するシーケンスを生成する
val x : float
val y : float
val loop : (Complex -> seq<Complex>)
val current : Complex
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val countIterations : max:int -> x:float -> y:float -> int

Full name: Japan-advent-art.countIterations
val max : int
module Seq

from Microsoft.FSharp.Collections
val take : count:int -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.take
val takeWhile : predicate:('T -> bool) -> source:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Collections.Seq.takeWhile
val v : Complex
Complex.Abs(value: Complex) : float
val length : source:seq<'T> -> int

Full name: Microsoft.FSharp.Collections.Seq.length
val clr : 'a
val count : 'b
val r1 : int
val g1 : int
val b1 : int
val count : int
val r2 : int
val g2 : int
val b2 : int
val c : int
val k : float
Multiple items
val float : value:'T -> float (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float

--------------------
type float = System.Double

Full name: Microsoft.FSharp.Core.float

--------------------
type float<'Measure> = float

Full name: Microsoft.FSharp.Core.float<_>
val mid : (int -> int -> int)
val v1 : int
val v2 : int
Multiple items
val int : value:'T -> int (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int

--------------------
type int = int32

Full name: Microsoft.FSharp.Core.int

--------------------
type int<'Measure> = int

Full name: Microsoft.FSharp.Core.int<_>
type Color =
  struct
    member A : byte
    member B : byte
    member Equals : obj:obj -> bool
    member G : byte
    member GetBrightness : unit -> float32
    member GetHashCode : unit -> int
    member GetHue : unit -> float32
    member GetSaturation : unit -> float32
    member IsEmpty : bool
    member IsKnownColor : bool
    ...
  end

Full name: System.Drawing.Color
Color.FromArgb(argb: int) : Color
Color.FromArgb(alpha: int, baseColor: Color) : Color
Color.FromArgb(red: int, green: int, blue: int) : Color
Color.FromArgb(alpha: int, red: int, green: int, blue: int) : Color
val palette : Color []

Full name: Japan-advent-art.palette
open System.Windows.Forms

let f = new Form(Visible=true, ClientSize=Size(400, 300))
let i = new PictureBox()
i.SizeMode <- PictureBoxSizeMode.Zoom
i.Dock <- DockStyle.Fill
f.Controls.Add(i)
val w : float * float

Full name: Japan-advent-art.w
val h : float * float

Full name: Japan-advent-art.h
val width : float

Full name: Japan-advent-art.width
val f : Form

Full name: Japan-advent-art.f
property Form.ClientSize: Size
property Size.Width: int
val height : float

Full name: Japan-advent-art.height
property Size.Height: int
val bmp : Bitmap

Full name: Japan-advent-art.bmp
Multiple items
type Bitmap =
  inherit Image
  new : filename:string -> Bitmap + 11 overloads
  member Clone : rect:Rectangle * format:PixelFormat -> Bitmap + 1 overload
  member GetHbitmap : unit -> nativeint + 1 overload
  member GetHicon : unit -> nativeint
  member GetPixel : x:int * y:int -> Color
  member LockBits : rect:Rectangle * flags:ImageLockMode * format:PixelFormat -> BitmapData + 1 overload
  member MakeTransparent : unit -> unit + 1 overload
  member SetPixel : x:int * y:int * color:Color -> unit
  member SetResolution : xDpi:float32 * yDpi:float32 -> unit
  member UnlockBits : bitmapdata:BitmapData -> unit
  ...

Full name: System.Drawing.Bitmap

--------------------
Bitmap(filename: string) : unit
   (+0 other overloads)
Bitmap(stream: System.IO.Stream) : unit
   (+0 other overloads)
Bitmap(original: Image) : unit
   (+0 other overloads)
Bitmap(filename: string, useIcm: bool) : unit
   (+0 other overloads)
Bitmap(type: System.Type, resource: string) : unit
   (+0 other overloads)
Bitmap(stream: System.IO.Stream, useIcm: bool) : unit
   (+0 other overloads)
Bitmap(width: int, height: int) : unit
   (+0 other overloads)
Bitmap(original: Image, newSize: Size) : unit
   (+0 other overloads)
Bitmap(width: int, height: int, format: Imaging.PixelFormat) : unit
   (+0 other overloads)
Bitmap(width: int, height: int, g: Graphics) : unit
   (+0 other overloads)
val x : int32
property Image.Width: int
val y : int32
property Image.Height: int
val x' : float
val snd : tuple:('T1 * 'T2) -> 'T2

Full name: Microsoft.FSharp.Core.Operators.snd
val fst : tuple:('T1 * 'T2) -> 'T1

Full name: Microsoft.FSharp.Core.Operators.fst
val y' : float
val it : int
property System.Array.Length: int
Bitmap.SetPixel(x: int, y: int, color: Color) : unit
val i : PictureBox

Full name: Japan-advent-art.i
property PictureBox.Image: Image
val palette : (float * float * float) []

Full name: Japan-advent-art.palette
val setPixel : img:ImageData -> x:'a -> y:'b -> width:'c -> r:'d * g:'e * b:'f -> unit

Full name: Japan-advent-art.setPixel
val img : ImageData
type ImageData

Full name: ImageData
val x : 'a
val y : 'b
val width : 'c
val r : 'd
val g : 'e
val b : 'f
val doc : Document
type Document =
  interface
    inherit MSNodeExtensions
    inherit MSResourceMetadata
    inherit DocumentEvent
    inherit MSEventAttachmentTarget
    inherit NodeSelector
    inherit Node
  end

Full name: Document
val name : 'a
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val render : unit -> Async<unit>

Full name: Japan-advent-art.render


 列毎にスリープしつつ、非同期的にフラクタルを描画する
val async : AsyncBuilder

Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.async
val canv : HTMLCanvasElement
type HTMLCanvasElement =
  interface
    inherit HTMLElement
  end

Full name: HTMLCanvasElement
type Globals

Full name: Globals
property Globals.document: Document
val ctx : CanvasRenderingContext2D
member HTMLCanvasElement.getContext_2d : unit -> CanvasRenderingContext2D
member CanvasRenderingContext2D.createImageData : imageDataOrSw:obj * ?sh:float -> ImageData
val x : int
val y : int
Multiple items
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken

Full name: Microsoft.FSharp.Control.Async

--------------------
type Async<'T>

Full name: Microsoft.FSharp.Control.Async<_>
static member Async.Sleep : millisecondsDueTime:int -> Async<unit>
member CanvasRenderingContext2D.putImageData : imagedata:ImageData * dx:float * dy:float * ?dirtyX:float * ?dirtyY:float * ?dirtyWidth:float * ?dirtyHeight:float -> unit
val go : HTMLButtonElement

Full name: Japan-advent-art.go
type HTMLButtonElement =
  interface
    inherit MSDataBindingExtensions
    inherit HTMLElement
  end

Full name: HTMLButtonElement
member HTMLElement.addEventListener_click : listener:System.Func<MouseEvent,obj> * ?useCapture:bool -> unit
static member Async.StartImmediate : computation:Async<unit> * ?cancellationToken:System.Threading.CancellationToken -> unit
val setPixel : img:ImageData -> x:int -> y:int -> width:int -> r:float * g:float * b:float -> unit

Full name: Japan-advent-art.setPixel


 ImageDataにあるピクセルの値を特定の色に設定する
val width : int
val r : float
val g : float
val b : float
val index : int
property ImageData.data: float array
val name : string
member Document.getElementById : elementId:string -> HTMLElement

Published: Tuesday, 24 December 2013, 3:58 AM
Author: Tomas Petricek
Typos: Send me a pull request!
Tags: f#, art, fractals, funscript, f# data