## 画像の操作とレンダリング

Cinderella.2 では、面の描画に関していろいろな方法があります。CindyScriptでメディア・データベースで画像を利用することができます。画像は、移動、回転、拡大縮小、射影変換などができます。他方、 CindyScript の描画関数を用いて、他の目的のための青写真的な利用ができます。

### メディアブラウザ

画像操作の前に、どのようにしてシンデレラの作品上に画像を載せるのかという問題があります。そのために「メディアブラウザ」があります。メディアブラウザを使うには、ファイルメニューの「メディアブラウザ」を選びます。するとポップアップウィンドウが出て、 +ボタンを押すと画像ファイルを読み込むことができてリストに追加できます。 - ボタンを押せばリストから削除されます。読み込んだ画像は、内部での名前とプレビューが表示されます。画像の名前は読み込んだファイルの名前ですが、ダブルクリックして名前を変更することができます。これは内部的な名前で、 CindyScriptではこの名前を使います。

メディアブラウザ

メディアブラウザ内の画像は、点や直線の代わりとして、また背景画像として使うことができます。使うにはインスペクタを用います。

### 画像の表示と変換

#### Drawing an image: `画像の表示(<pos>,<imagename>)`

説明: この関数は、メディアブラウザから画像を取り出して、第1引数で示した点に表示します。初期状態では点の中心が画像の中心になりますが、これは修飾子によって変更することができます。また、画像の拡大縮小と配置も変えることができます。
例: 次のコードでは、 `MyImage` 画像を点Aの位置に表示します。

    drawimage(A,"MyImage"))

次の例は `drawimage` 関数のいろいろな使い方を示します。

    drawimage(A,"myimage");
    drawimage(B,"myimage",scale->1.5,angle->30°);
    drawimage(C,"myimage",ref->"lb");

参照点: 参照点を指定するのに精巧な方法があります。それは、修飾子`ref`, `refx`, `refy` を用いることです。最初のものは２次元情報を示し、あとの２つがそれぞれ座標の方向を示します。参照情報は３つの異なる方法で与えられます。

- もとの画像の画素数への絶対参照。たとえば、元の画像の画素数が 400x800 のとき、修飾子 `ref->[100,200]` により、左下4分の1のところが参照点になります。
- 比率で参照。この場合、百分率で位置を示します。たとえば、`ref->["25%", "25%"]` とすれば左下4分の1のところの参照点を置きます。
- 2つの文字で記号的に。ここで x方向 を `l`, `c`, `r`で、順に 左、中央、右、y方向を letters `b`, `c`, `t` で下、中央、上とします。すると左下は `ref->"lb"` または `ref->["l","b"]` で表されます。

位置情報は２つの方向に分けて指定することもできます。たとえば、`refx->"l"`, `refx->100` あるいは `refx->"10%"` のようにです。次の図はいくつかの参照点を示します。

修飾子: いくつかの修飾子があります。

修飾子 | 型 | 効果:
`alpha` | `0.0 ... 1.0` | 画像の透明度
`angle` | `実数` | 参照点周りの回転角
`rotation` | `実数` | `angle`と同じ
`scale` | `実数` | 拡大縮小
`scale` | `ベクトル` | それぞれの方向に拡大縮小
`scalex` | `実数` | x軸方向へ拡大縮小
`scaley` | `実数` | y軸方向へ拡大縮小
`flipx` | `ブール値` | 垂直方向に反転
`flipy` | `ブール値` | 水平方向に反転
`ref` | `上記説明参照` | 参照点の位置指定
`refx` | `上記説明参照` | 参照点の x 軸方向の位置指定
`refy` | `上記説明参照` | 参照点の y 軸方向の位置指定
`rendering` | `"fast"` または `"nice"` | 表示品質

#### 画像表示: `drawimage(<pos>,<pos>,<imagename>)`

説明: 位置と大きさを２つの参照点で指定して画像を表示します。初期状態では２つの参照点は画像の下辺の両端となります。この参照点を画像内の他の点にすることもできます。その方法は先ほどのものと同じです。
例: 最も簡単な使い方は次の通りです。

    drawimage(A,B,"myimage"))

修飾子を用いた方法は以下のようになります。２つの参照点や表示の比率がどのように指定されているかに注目してください。

    drawimage(A,B,"MyImage");
    drawimage(C,D,"MyImage",aspect->1);
    drawimage(E,F,"MyImage",flipx->true);
    drawimage(G,H,"MyImage",refx1->"20%",refy1->"50%",ref2->"rt");

修飾子: この関数にはいくつかの修飾子があります。

修飾子: | 型 | 効果:
`alpha` | `0.0 ... 1.0` | 画像の透明度
`flipx` | `ブール値` | 垂直方向に反転
`flipy` | `ブール値` | 水平方向に反転
`aspect` | `実数` | アスペクト比
`ref1` | `上記参照` | １つめの参照点の位置指定
`refx1` | `上記参照` | １つめの参照点の x 軸方向の位置指定
`refy1` | `上記参照` | １つめの参照点の y 軸方向の位置指定
`ref2` | `上記参照` | 2つめの参照点の位置指定
`refx2` | `上記参照` | 2つめの参照点の x 軸方向の位置指定
`refy2` | `上記参照` | 2つめの参照点の y 軸方向の位置指定
`rendering` | `"fast"` または `"nice"` | 表示品質

例: より進んだ使い方は次の通りです。変換行列によって2つの参照点を反復的に変化させます。それぞれのステップで画像を表示していきますが、それは対数螺旋を描きます。多くの画像を表示するために一つ問題があります。それは表示速度です。場合によってはきれいに表示するか、速く表示するかを選択する必要があるでしょう。そのための修飾子が `rendering` で、 `nice` か `fast` を設定します。初期状態では `nice` になっています。

    a=(1,0);
    b=(2,-1);
    w=30°;
    m=((cos(w),-sin(w)),
       (sin(w),cos(w)))*0.9;

    repeat(100,
     drawimage(a,b,"MyImage");
     a=m*a;
     b=m*b;
    );

#### 画像の表示: `drawimage(<pos>,<pos>,<pos>,<imagename>)`

説明: ３つの参照点を用いてアフィン変換をします。初期状態では、画像の底辺の左右と左上の点です。参照点は修飾子で変更することができます。
例: 最も簡単な使い方は次の通りです。

    drawimage(A,B,C,"MyImage"))

この関数は、反転や回転のような幾何学的変換をして画像を表示するのに適しています。そのためには、参照点を変換した点を用意します。次の例をご覧ください。点A' , B' , C ' は点A,B,Cを直線に関して鏡像変換（反転）した点です。

    drawimage(A,B,C,"MyImage"))
    drawimage(A',B',C',"MyImage"))

修飾子: この関数には次の修飾子が追加されます。

修飾子: | 型 | 効果:
`ref3` | `上記参照` | ３つめの参照点の位置指定
`refx3` | `上記参照` | ３つめの参照点の x 軸方向の位置指定
`refy3` | `上記参照` | ３つめの参照点の ｙ 軸方向の位置指定

#### 画像の表示: `drawimage(<pos>,<pos>,<pos>,<pos>,<imagename>)`

説明: ４つの参照点を指定して射影変換をします。初期状態では参照点は左下から４つの角の点を反時計回りにとられます。
例: 最も簡単な使い方は次の通りです。

    drawimage(A,B,D,C,"myimage")

次の図がこの結果です。わかりやすくするために格子を描いてあります。（上のコードで格子が描かれるわけではありません）

修飾子: つぎの修飾子が追加されます。

修飾子: | 型 | 効果:
`ref4` | `上記参照` | ４つめの参照点の位置指定
`refx4` | `上記参照` | ４つめの参照点の x 軸方向の位置指定
`refy4` | `上記参照` | ４つめの参照点の ｙ 軸方向の位置指定

#### 画像をデフォルメする: `mapimage(<imagename>,<function>)`

説明: この関数は、引数の関数を用いて画像を変形させます。通常、この関数は、ある関数を用いて２次元ベクトルを２次元ベクトルに写すものとします。complex 修飾子を用いて複素数平面から複素数平面へ写すこともできます。関数の範囲は x-range と y-range 修飾子で指定しますが、指定がなければ0.0と1.0の間とされます。この範囲が画像の長方形の縦横幅に対応します。この範囲ですべての点が写されます。この機能は基本的に `mapgrid`関数と類似しています。
例: ここでは、x軸方向をsin関数を使って変形します。まず、その関数を定義します。次に `mapimage` 関数で変形します。図では、わかりやすくするために方眼を描いています。

    f(z):=(z_1*(sin(z_2)+1.3),z_2);
    mapimage("MyImage",f(#),
    xrange->(-1,1),
    yrange->(0,pi),resolution->30
    );
    mapgrid(f(#),color->(0,0,0),alpha->0.3,
    xrange->(-1,1),
    yrange->(0,pi),resolution->30
    );

やせた Ritter Rost

次の例は前のものと類似していますが、関数として複素関数を用いています。

    r=complex(A);
    f(x):=exp(r*x);
    mapimage("myimage",f(#),
      complex->true,
      xrange->(0,1),
      yrange->(0,pi),resolution->30
    );

    mapgrid(f(#),complex->true,
    xrange->(0,1),yrange->(0,pi),color->(0,0,0),alpha->0.5
    ,resolutiony->30,resolutionx->10,step->10,size->1);

修飾子: 次のような修飾子があります。

修飾子: | 型 | 効果:
`alpha` | `0.0 ... 1.0` | 画像の透明度
`xrange` | `ベクトル` | x軸方向の範囲
`yrange` | `ベクトル` | y軸方向の範囲
`complex` | `ブール値` | 複素関数を用いるフラグ
`resolution` | `整数` | 変換後の画像の解像度

#### 画像の大きさを取得する: `imagesize(<imagename>)`

説明: 画像の大きさを返します。戻り値は幅と高さの画素数を示す２つの整数です。

#### 画素情報を取得する: `imagergb(<imagename>,<int>,<int>)`

説明: `imagergb(<imagename>,x,y)` で、(x,y) の位置にある画素の色情報を取得します。戻り値は4次元のベクトルで、はじめの3つはRGB値(0〜255)、4番目はアルファ値です。
例: 次のコードでは、まず画像を表示してその大きさを取得します。次に、両方向に標本点を取り、その色と透明度で粗っぽい点からなる画像を作成します。

    drawimage(A,"MyImage",scale->2);
    dim=imagesize("MyImage");
    forall((0..dim_1/10)*10,i,err(i);
      forall((0..dim_2/10)*10,j,
        col=imagergb("MyImage",i,j);
        draw((i,-j)*.03,color->(col_1,col_2,col_3)/255,
                        alpha->col_4,
                        border->false)
      )
    )

### カスタム画像を作る

ここまでは、メディアブラウザであらかじめ読み込まれた画像についての操作でしたが、シンデレラの描画面から画像を作ることもできます。いったん画像として作ってしまえば、
`CindyScript の`canvas`関係の関数でそれを操作することができます。これにより、描画のための命令などは見えなくなります。しかし、カスタム画像が作られればそれを描画手順のうちの一つとして画面上に描くことができます。画像表示は描画と似て、画面の任意の場所に描くことができます。この概念はとても強力ですが、基本的な使い方を示すだけにします。`

#### カスタム画像を作る: `createimage(<imagename>,<int>,<int>)`

説明: `createimage(<imagename>,width,height)` 関数は、指定された画像のイメージバッファを作成します。最初はそこには何もありません。イメージバッファはメディアブラウザのもとで指定した名前でアクセス可能となり、 `drawimage(...)` 関数で使えるようになります。

#### 画像の内容を消去: `clearimage(<imagename>)`

説明: この関数は、画像からすべての内容を消去します。消去後も画像は存在しますが、描画された内容はなく、いわば透明な状態です。

#### 画像の削除: `removeimage(<imagename>)`

説明: この関数はメディアブラウザから画像を取り除きます。これ以降アクセスすることはできなくなります。

### キャンバスに描く

画像をキャンバスのようにして、CindyScript で描画をすることができます。これは強力な概念ですが、若干の説明を要するでしょう。
次のコードで同心円を作図したとしましょう。

     linesize(3);
     repeat(10,i,
       drawcircle(K,i*.5);
     );
     drawtext(K+(-2,2),"These are",size->20,color->(1,1,0));
     drawtext(K+(-2,-2),"some circles",size->20,color->(1,1,0));

この結果は左図のようになります。いま、このコードを使って右図のようなビットマップ画像を作成したいとします。そのための画像をあらかじめ作っておきます。
`initialization スロットに、次のようなコードを書くことによって、画像が用意できます。`

    createimage("image",400,400)

この画像を、キャンバスと見立てます。今の例では、4つの点で指定した長方形をそのキャンバスに対応させます。

    canvas(F,G,E,"image"
        //....here comes the drawing code....
    )

３つの頂点 F, G, E でキャンバスの位置が指定されます。上の図の長方形EFGHです。実際には、`canvas`内でのすべての描画命令による図は目に見えないので、上の図は説明のためのものです。
図を描いたあとは、 `drawimage(...)` 関数を用いて図を表示することができます。その結果を例示すると次のようになります。

    clearimage("image");
    canvas(F,G,E,"image",
     linesize(3);
     repeat(10,i,
       drawcircle(K,i*.5);
     );
     drawtext(K+(-2,2),"These are",size->20,color->(1,1,0));
     drawtext(K+(-2,-2),"some circles",size->20,color->(1,1,0));
    );

    drawimage(A,B,C,D,"image");

ここで使われる`drawimage(...)` 関数では、射影変換をしています。その結果は次の図の通りです。
キャンバスの画像はビットマップであることに注意してください。したがって適切な解像度を指定しなければなりません。初期値として 80×80 のサイズにすると次の図のようになるでしょう。いったんキャンバスが作られると、それが異なる場所や大きさで使われることがあるでしょう。次のコードで、そのような例を示します。

    drawimage(A,P,M,O,"image");
    drawimage(B,P,M,Q,"image");
    drawimage(D,R,M,O,"image");
    drawimage(C,R,M,Q,"image");

#### キャンバスに描く (参照点１つ): `canvas(<pos>,<imagename>,<drawing code>)`

説明: この関数は `<imagename>` の画像をキャンバスとして用い、１つの参照点に対して`drawimage(<pos>,<imagename>)` 関数で表示をします。 `<drawing code>` によりキャンバス上に描画します。 修飾子は `drawimage(<pos>,<imagename>)`と同様です。
修飾子: The command has several 修飾子.

修飾子 | 型 | 効果:
`angle` | `実数` | 参照点周りの回転角
`rotation` | `実数` | `angle`と同じ
`scale` | `実数` | 拡大縮小
`scale` | `ベクトル` | それぞれの方向に拡大縮小
`scalex` | `実数` | x軸方向へ拡大縮小
`scaley` | `実数` | y軸方向へ拡大縮小
`flipx` | `ブール値` | 垂直方向に反転
`flipy` | `ブール値` | 水平方向に反転
`ref` | `上記説明参照` | 参照点の位置指定
`refx` | `上記説明参照` | 参照点の x 軸方向の位置指定
`refy` | `上記説明参照` | 参照点の y 軸方向の位置指定

#### キャンバスに描く (参照点2つ): `canvas(<pos>,<pos>,<imagename>,<drawing code>)`

説明: この関数は `<imagename>` の画像をキャンバスとして用い、２つの参照点に対して表示をします。 `<drawing code>` によりキャンバス上に描画します。 修飾子は `drawimage(<pos>,<pos>,<imagename>)`と同様です。
修飾子: 修飾子がいくつかあります。

修飾子: | 型 | 効果:
`flipx` | `ブール値` | 垂直方向に反転
`flipy` | `ブール値` | 水平方向に反転
`aspect` | `実数` | アスペクト比
`ref1` | `上記参照` | １つめの参照点の位置指定
`refx1` | `上記参照` | １つめの参照点の x 軸方向の位置指定
`refy1` | `上記参照` | １つめの参照点の y 軸方向の位置指定
`ref2` | `上記参照` | 2つめの参照点の位置指定
`refx2` | `上記参照` | 2つめの参照点の x 軸方向の位置指定
`refy2` | `上記参照` | 2つめの参照点の y 軸方向の位置指定

#### キャンバスに描く (参照点3つ): `canvas(<pos>,<pos>,<pos>,<>,<drawing code>)`

説明: 上の関数と同様で、３つの参照点で描画します。
修飾子: この関数には次の修飾子が追加されます。

修飾子: | 型 | 効果:
`ref3` | `上記参照` | ３つめの参照点の位置指定
`refx3` | `上記参照` | ３つめの参照点の x 軸方向の位置指定
`refy3` | `上記参照` | ３つめの参照点の ｙ 軸方向の位置指定

Page last modified on Tuesday 06 of March, 2012 [13:17:02 UTC].
The original document is available at http://doc.cinderella.de/tiki-index.php?page=Image%20Manipulation%20and%20RenderingJ