はじめに
最近、HTML5の記事をよく見かけるようになりました。次世代のHTML規格であるHTML5は、画像や動画などグラフィック関連の表現がサポートがされることで注目を集めています。
今回は、その中のcanvasタグに焦点を当ててみたいと思います。HTML5ではcanvasタグとJavaScriptを用いて、容易に2次元グラフィックを表現できるようになります。canvasタグはInternet Explorer 8ではサポートされていませんが、他のブラウザではサポートされており、表現力の点からも今後は普及していく方向に進むのではないでしょうか。
本記事では、canvasタグ実装とCurl実装の比較を交えて、Curlでの2次元グラフィックスについて紹介します。Curlでは当初より2次元グラフィックス、3次元グラフィックスを標準機能として提供しています。今回は、グラデーション表現とイメージの加工について説明していきたいと思います。
なお、文中のサンプルは添付のサンプルコードでも確認できます。
開発手順
- グラデーション表現
- イメージ加工
開発環境
- Curl RTE 7.0
1.グラデーション表現
canvasとの実装比較として、双方のイメージとソースコードを用いて説明していきます。まずは縦方向のグラデーションからです。

{curl 7.0 applet}
{View
{Fill … 1
width = 2in, … 2
height = 2in,
background = {LinearGradientFillPattern … 3
{Fraction2d 0, 0}, … 4
{Fraction2d 1, 0},
{Spectrum.from-envelope … 5
"#C05050", 0.0,
"#C0C050", 0.5,
"#5050C0", 1.0
}
}
},
visibility = "normal",
{on WindowClose do
{exit}
}
}

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>グラデーション(縦)</title>
<script type="text/javascript">
onload = function() {
draw();
};
function draw() {
var canvas = document.getElementById('base');
var context = canvas.getContext('2d');
context.beginPath();
var linerGrad = context.createLinearGradient(0, 0, 200, 0); … 2
linerGrad.addColorStop(0.0, "#C05050"); … 3
linerGrad.addColorStop(0.5, "#C0C050");
linerGrad.addColorStop(1.0, "#5050C0");
context.fillStyle = linerGrad; … 4
context.rect(0, 0, 200, 200); … 5
context.fill();
}
</script>
</head>
<body>
<header><h1>グラデーション(縦)</h1></header>
<canvas id="base" width="200" height="200"></canvas> … 1
</body>
</html>
最初なので各々のソースコードを説明します。
Curl実装
- Fillシェイプを生成します。
- Fillシェイプの大きさを指定します。
- Fillシェイプの背景として、線形グラデーション塗りつぶしパターンを設定します。
- 線形グラデーション塗りつぶしパターンの線形方向をX軸方向とします。
- 塗りつぶし色として、Spectrumによりカスタムカラーマップを設定します。引数は、色、位置の繰り返しとなります。
canvas実装
- canvasタグを定義し、idを設定しておきます。
- canvasオブジェクトより取得した2次元コンテキストを用いて、線形グラデーションを生成します。引数は線形方向を表し、この例ではX軸方向となります。
- 線形グラデーションのパラメータを指定します。パラメータは、最初の値が開始位置、次の値が色を表します。開始位置は0.0~1.0の範囲内で指定します。
- 塗りつぶし色として、線形グラデーションを指定します。
- 矩形を描画します。
ソースコードを見ると、似かよった構成となっていることがわかると思います。ただしcanvasの場合、線形方向のサイズがグラデーションのサイズを決定しているため、以下のようにサイズを小さくすると、グラデーションの結果も変わってしまいます。つまり、canvasではグラデーションの実体イメージが作成され、それを用いて塗りつぶされていると推測されます。
var linerGrad = context.createLinearGradient(0, 0, 100, 0);

以下、横方向、斜め方向のグラデーションです。縦方向との違いは線形方向の指定部分のみです。
Curl実装


Canvas実装


イメージのクリッピング
次にイメージのクリッピングについても簡単に解説します。どちらも以下のような三角形のクリッピングが可能です。Curlとcanvas両者でアプローチは異なっており、Curlでは、Renderer2d.render-triangleメソッドで三角形を描画する際に、塗りつぶしパターンとしてグラデーションを指定しているのに対し、canvasでは三角形のクリッピング領域を設定して、矩形のグラデーションを描画しています。
また、CurlではFrameなどの描画オブジェクトのdrawメソッドをオーバーライドし、引数で渡されるRenderer2dを用いて描画を行います。
Curl実装

Canvas実装

{define-proc {tri-proc ren:Renderer2d}:void
let fp:FillPattern = {LinearGradientFillPattern
{Fraction2d 0, 0},
{Fraction2d 1, 0},
{Spectrum.from-envelope
"#C05050", 0.0,
"#C0C050", 0.5,
"#5050C0", 1.0
}
}
{ren.render-triangle
{Distance2d 1cm, 4cm},
{Distance2d 4cm, 1cm},
{Distance2d 0cm, 0cm},
fill-pattern = fp
}
}
{define-class RepaintFrame {inherits Frame}
{constructor {default ...}
{construct-super ...}
}
{method public {draw ren:Renderer2d}:void
{tri-proc ren}
}
}
グラデーションパターンの部分的な使用
次は、イメージのグラデーションパターンの部分的な使用についてです。この例では、Renderer2d.render-rectangleメソッドのテクスチャ座標パラメータを指定し、元のグラデーションパターン全体を1と考えた時の0.3~0.7の領域を切り出したグラデーションを用いて描画しています。

{ren.render-rectangle
0.5cm, 0.5cm, 2.0cm, 2.0cm,
fill-pattern = fp,
uv1 = {Fraction2d .3, .3},
uv2 = {Fraction2d .7, .7}
}
以上、グラデーションおよび2次元描画について、駆け足ではありましたが紹介しました。ここで紹介はできませんでしたが、Renderer2dにはさまざまな描画メソッドが提供されています。
閉じた図形の描画メソッド
- Renderer2d.render-ellipse
- Renderer2d.render-polygon
- Renderer2d.render-polygon-from-array
- Renderer2d.render-rectangle
- Renderer2d.render-rounded-rectangle
- Renderer2d.render-stippled-rectangle
- Renderer2d.render-region
- Renderer2d.render-triangle
線図形の描画メソッド
- Renderer2d.render-elliptic-path
- Renderer2d.render-path
- Renderer2d.render-rectangular-path
- Renderer2d.render-rounded-rectangular-path
- Renderer2d.render-line
その他の図形の描画メソッド
- Renderer2d.render-drawable…指定されたDrawableのすべてまたは一部をレンダリングします。
- Renderer2d.render-pixmap…指定されたPixmapのすべてまたは一部をレンダリングします。
- Renderer2d.render-string…指定されたStringのすべてまたは一部をレンダリングします。
2.イメージ加工
イメージ加工として、Curlにはさまざまなフィルタが用意されています。その一部を紹介します。
まずは、“ぼかし”フィルタです。これは、元となるFillPatternにフィルタ加工を行い、フィルタ加工後のFillPatternを用いて描画を行います。ソースコードの太字部分がフィルタ加工処理になります。ここでは、60%の“ぼかし”を行っています。
“ぼかし”の例

{curl 7.0 applet}
{import * from CURL.GRAPHICS.IMAGEFILTER}
{let src-fp:FillPattern =
{FillPattern.from-url {url "curl://install/docs/default/images/adria.jpg"}}}
{let blurred-fp:FillPattern =
{blur
src-fp, || in FillPattern
amount=60%, || amount to blur the image
out=null} || out FillPattern
}
{View
{Fill
width = 2.5in, height = 2.5in,
background = blurred-fp
},
visibility = "normal",
{on WindowClose do
{exit}
}
}
もう1つの例として、RGBの各色値単位に割合指定を行うフィルタです。このフィルタを用いて、色分解を行ったりすることができます。以下の例では、R値を1.5倍、G値・B値を0.5倍しています。

{curl 7.0 applet}
{let fp-org:FillPattern =
{FillPattern.from-url {url "curl://install/docs/default/images/adria.jpg"}}}
{let fp:FillPattern =
{IMAGEFILTER.rgb-scale
fp-org,
red=1.5, green=0.5, blue=0.5
}}
{View
{HBox
{Fill width=1in, height=1in, background=fp-org},
{Fill width=1in, height=1in, background=fp}
},
visibility = "normal",
{on WindowClose do
{exit}
}
}

提供フィルタ一覧
最後に、提供されているフィルタの一覧をまとめておきます。
autolevel
低照明の矯正
blend
2つのFillPattern を混合

blur
"ぼかし" 効果
brightness-adjust
明度調節
bubble
泡表示

contrast-adjust
コントラスト レベルを調整
emboss
エンボス効果

filter-pixmap
Pixmapにしてイメージ フィルタを実施
glow
"glow" 効果

hsv-adjust
色相、彩度、およびイメージの値 (またはそのうちのどれか) を調整
rgb-channel
赤、緑、青、およびアルファの各チャネルの除外
rgb-offset
赤、緑、青、およびアルファのチャネルに個々に値を付加
rgb-scale
赤、緑、青、およびアルファのチャネルを個々の係数で乗算
rotate
回転

scale
水平方向と垂直方向のスケール変更

skew-height
垂直方向に補正

skew-width
水平方向に補正

sphere丸く歪める

translate
平行移動
twirl
渦巻き

warp
ワープ



