Glow.cs
//
// このコードは、DioDocs for Imaging のサンプルの一部として提供されています。
// © MESCIUS inc. All rights reserved.
//
using System;
using System.IO;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using GrapeCity.Documents.Drawing;
using GrapeCity.Documents.Text;
using GrapeCity.Documents.Imaging;
using GCTEXT = GrapeCity.Documents.Text;
using GCDRAW = GrapeCity.Documents.Drawing;
namespace DsImagingWeb.Demos
{
// このサンプルでは、DsImaging を使用してグロー効果を作成する方法を示します。
// グロー効果は、画像内のすべての非透明領域を指定した量だけ拡張し、
// その後ガウシアンブラーを適用して境界を滑らかにします。
// これは、例えば MS Word にも用意されている効果の一つです。
//
// DsImaging でこの効果を実現するには、グローを適用したいカラー画像から
// 作成した透明マスクに対して GrayscaleBitmap.ApplyGlow() メソッドを使用し、
// 本コードで示すいくつかの簡単な手順を組み合わせます。
//
// また、内容(テキストおよび画像)をぼかした上に、
// 元の内容を再度描画することでグロー効果を実現しています。
// 別の方法については、内容を二重に描画せずに済む GlowAlt を参照してください。
//
// 同じ GrayscaleBitmap.ApplyGlow() メソッドは、
// SoftEdges の例で示されているソフトエッジ効果の実現にも使用されます。
public class Glow
{
private GCTEXT.Font _font = GCTEXT.Font.FromFile(Path.Combine("Resources", "Fonts", "FreeSans.ttf"));
public GcBitmap GenerateImage(Size pixelSize, float dpi, bool opaque, string[] sampleParams = null)
{
// 透明なビットマップ上にテキストとロゴを描画します。
var bmp = new GcBitmap(pixelSize.Width, pixelSize.Height, false);
bmp.Clear(Color.Transparent);
drawTextAndLogo();
// 画像を透過マスクに変換します。
using var gs = bmp.ToGrayscaleBitmap(ColorChannel.Alpha);
// 光彩(Glow)エフェクトを適用します。ソフトエッジ(Soft Edges)の場合は、
// 膨張半径を負の値に設定しますが、光彩の場合は正の値にする必要があります。
// ここでは6に設定しています(9はぼかし半径です)。
gs.ApplyGlow(6, 9);
// 透過マスクからソースのGcBitmapにシャドウをマッピングします。
// 不透明なピクセルを光彩の色(黄色)で描き、さらに透明度を適用します。
gs.ToShadowBitmap(bmp, Color.Yellow, 0.8f);
// 背景を塗りつぶします。
bmp.ConvertToOpaque(Color.Gray);
// 最後に、準備した背景の上にテキストとロゴをもう一度描画します。
drawTextAndLogo();
return bmp;
void drawTextAndLogo()
{
var renderer = bmp.EnsureRendererCreated();
DrawText(renderer, pixelSize, dpi);
DrawLogo(renderer, new PointF(pixelSize.Width / 2, (int)(pixelSize.Height * 0.8)), pixelSize.Width / 2);
}
}
void DrawText(BitmapRenderer renderer, Size pixelSize, float dpi)
{
var f1 = new TextFormat
{
Font = _font,
FontSize = pixelSize.Height / 7,
ForeColor = Color.DarkOrchid,
FontBold = true
};
var f2 = new TextFormat(f1)
{
ForeColor = Color.White,
StrokePen = new GCDRAW.Pen(Color.DarkOrchid, 3)
};
var tl = new TextLayout(dpi)
{
MaxWidth = pixelSize.Width,
MaxHeight = pixelSize.Height,
ParagraphAlignment = ParagraphAlignment.Near,
TextAlignment = TextAlignment.Center,
MarginTop = dpi * 2,
LineSpacingScaleFactor = 0.7f,
};
tl.AppendLine("MESCIUS", f1);
tl.AppendLine("DioDocs", f2);
// テキストを描画します。
renderer.SlowAntialiasing = true;
renderer.DrawTextLayout(tl, 0, 0);
}
void DrawLogo(BitmapRenderer renderer, PointF center, float width)
{
var pb = new PathBuilder();
float refCenterX = 400;
float refCenterY = 300;
float outerRadius = 250;
float innerRadius = 100;
int points = 5;
for (int i = 0; i < points * 2; i++)
{
double angle = i * Math.PI / points - Math.PI / 2;
float r = (i % 2 == 0) ? outerRadius : innerRadius;
float x = refCenterX + (float)(Math.Cos(angle) * r);
float y = refCenterY + (float)(Math.Sin(angle) * r);
if (i == 0)
pb.BeginFigure(x, y);
else
pb.AddLine(x, y);
}
pb.EndFigure(true);
var gpFill = pb.ToPath();
var gpStroke = gpFill.Widen(new GCDRAW.Pen(Color.Black, 20));
// 基本となるサイズは 800 x 600 ピクセルです。
float scale = width / 800;
renderer.Transform = Matrix3x2.CreateScale(scale) *
Matrix3x2.CreateTranslation(center.X - 400 * scale, center.Y - 300 * scale);
renderer.FillPath(gpFill, Color.CornflowerBlue);
renderer.FillPath(gpStroke, Color.DarkOrchid);
renderer.Transform = Matrix3x2.Identity;
}
}
}