岩のテクスチャを用いて、岩でできたような盛り上がった文字を描画する方法を紹介します。
エンボスの実装
盛り上がりを表現するには、DistantLitDiffuseという、遠くにある並行光源による拡散反射をシミュレートするイメージフィルターを使用します。具体的なフィルタの構成は以下の通りです。
- ブレンド合成 DstIn(SrcのアルファをDstに適用)
- ブレンドのDst側
- ブレンド合成 HardLight(Srcの明るさをDstに適用)
- ブレンドのDst側
- 岩テクスチャ(岩の画像を読み込んでSKImageに変換したもの)
- ブレンドのSrc側
- エンボスフィルター(DistantLitDiffuse)
- ぼかしフィルター(Blur)
- エンボスフィルター(DistantLitDiffuse)
- ブレンドのSrc側(元の描画)
- ブレンドのDst側
using var paint = new SKPaint {
Color = SKColors.Black,
IsAntialias = true,
};
paint.ImageFilter =
// ブレンドモードDstIn(SrcのアルファをDstに適用)
SKImageFilter.CreateBlendMode(
SKBlendMode.DstIn,
// Dst: ブレンドモードHardLight
SKImageFilter.CreateBlendMode(
SKBlendMode.HardLight,
// Dst: 岩テクスチャ
SKImageFilter.CreateImage( imageRock ),
// Src: エンボスフィルター
SKImageFilter.CreateDistantLitDiffuse(
// 光源の位置
new SKPoint3( -1, -1, 1 ),
// 光源の色
SKColors.White,
// 高さのスケール
3.0f,
// 拡散反射係数(正規化された光のベクトルのZ成分×0.5 とする)
(float)( 0.5 * Math.Sqrt( 3 ) ),
// 入力画像: ぼかしフィルター
SKImageFilter.CreateBlur(
// 横方向ぼかし半径
2,
// 縦方向ぼかし半径
2
)
)
)
// Src: 省略(元図形)
);
using var font = new SKFont( typefaceArialBlack, 100 );
canvas.DrawText( "Skia", 25, 140, font, paint );
実行すると、以下のように、岩のテクスチャが適用された盛り上がった文字が描画されます。
もっとシャープに
先程の実装では、Blurフィルターでぼかしてエンボスにしたため、少し角が丸い感じになってしまいました。もっとシャープにしたい場合は、テーブル変換フィルターを追加して、エンボスのコントラストを上げます。具体的なフィルタの構成は以下の通りです。
- ブレンド合成 DstIn(SrcのアルファをDstに適用)
- ブレンドのDst側
- ブレンド合成 HardLight(Srcの明るさをDstに適用)
- ブレンドのDst側
- 岩テクスチャ(岩の画像を読み込んでSKImageに変換したもの)
- ブレンドのSrc側
- テーブル変換フィルター
- エンボスフィルター(DistantLitDiffuse)
- ぼかしフィルター(Blur)
- エンボスフィルター(DistantLitDiffuse)
- テーブル変換フィルター
- ブレンドのSrc側(元の描画)
- ブレンドのDst側
int amp = 64; // 明暗の振れ幅
int gain = 5; // コントラスト調整値
// 変換テーブルを作成
byte[] table = new byte[ 256 ];
for ( int i = 0 ; i < 256 ; i++ ) {
if ( i == 127 || i == 128 ) {
table[ i ] = (byte)i;
} else {
table[ i ] = (byte)Math.Clamp( (int)( ( i - 128 ) * gain + 128 ), 128 - amp, 128 + amp );
}
}
// ペイントのイメージフィルターを設定
paint.ImageFilter =
// ブレンドモードDstIn(SrcのアルファをDstに適用)
SKImageFilter.CreateBlendMode(
SKBlendMode.DstIn,
// Dst: ブレンドモードHardLight
SKImageFilter.CreateBlendMode(
SKBlendMode.HardLight,
// Dst: 岩テクスチャ
SKImageFilter.CreateImage( imageRock ),
// Src: テーブル変換フィルター
SKImageFilter.CreateColorFilter(
// R,G,B全チャンネル共通の変換テーブル
SKColorFilter.CreateTable(
table
),
// 入力画像: エンボスフィルター
SKImageFilter.CreateDistantLitDiffuse(
// 光源の位置
new SKPoint3( -1, -1, 1 ),
// 光源の色
SKColors.White,
// 高さのスケール
3.0f,
// 拡散反射係数
(float)( 0.5 * Math.Sqrt( 3 ) ),
// 入力画像: ぼかしフィルター
SKImageFilter.CreateBlur(
// 横方向ぼかし半径
1.5f,
// 縦方向ぼかし半径
1.5f
)
)
)
)
// Src: 省略(元図形)
);
実行すると、以下のように、シャープな盛り上がった文字が描画されます。
総合目次

