C# 文字の色を部分的に変えて描画する ＋ JavaScriptでもやってみた

# やりたいこと
カラオケの字幕のような感じで描画する。

# 画面キャプチャ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/7fc68fbb-f3c1-4290-9153-0c28f9dbe8f2.png)


# ソースコード

```csharp

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Windows.Forms;

class DrawStrSample : Form
{
    static readonly int W = 400;
    static readonly int H = 200;
    PictureBox pct;

    DrawStrSample()
    {
        ClientSize = new Size(W,H);

        Controls.Add(pct = new PictureBox(){
            Size = new Size(W,H),
            Image = new Bitmap(W,H),
        });

        Load += (s,e)=>{Draw("てすと");};
    }

    void Draw(string text)
    {
        var g = Graphics.FromImage(pct.Image);

        var rectDraw = new Rectangle(0, 0, W, H);
        
        int leftPartWitdh = (int)(rectDraw.Width * 0.45);

        // 左側用と右側用の、色と描画領域
        Brush[] brush = { new SolidBrush(Color.Blue)     , new SolidBrush(Color.Gray)      };
        Pen[]   pen   = {        new Pen(Color.Blue,3.0f),        new Pen(Color.Gray,3.0f) }; // 表示確認用
        Rectangle[] rectClip = {
            new Rectangle(rectDraw.X,                 rectDraw.Y,                  leftPartWitdh, rectDraw.Height), 
            new Rectangle(rectDraw.X + leftPartWitdh, rectDraw.Y, rectDraw.Width - leftPartWitdh, rectDraw.Height)
        };

        // g.FillRectangle(Brushes.Gray, rectDraw);

        // DrawStringにアンチエイリアスを適用する
        // g.TextRenderingHint = TextRenderingHint.AntiAlias;
        
        // アンチエイリアスを適用する
        g.SmoothingMode = SmoothingMode.HighQuality;
        

        var gp = new GraphicsPath();
        var ff = new FontFamily("ＭＳ ゴシック");
        var sf = new StringFormat();
        sf.Alignment = StringAlignment.Center;
        //           String, FontFamily, fontStyle, emSize, layoutRect, StringFormat
        gp.AddString(text, ff, 0, 100, rectDraw, sf);
        
        // 左右をクリップを切り替えながら、２度描画する
        for ( int i=0; i<2; i++ ) {
            g.SetClip(rectClip[i]);
            //g.DrawString(text, font, brush[i], rectDraw , sf);

            //文字列の中を塗りつぶす
            g.FillPath(brush[i], gp);

            g.DrawRectangle(pen[i], rectClip[i]); // 確認用
        }

        // clipを元に戻す
        g.SetClip(rectDraw);
        //文字列の縁を描画する
        g.DrawPath(Pens.Black, gp);
        
        g.Dispose();
    }
    
    [STAThread]
    static void Main(string[] args)
    {
        Application.Run(new DrawStrSample());
    }
}
```

# 参考サイト （Ｃ＃）

- [「C#の画像作成で文字を部分的に色を変えたい」（1） Insider.NET － ＠IT](https://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=47855&forum=7)
- [.NET GraphicsPath.AddStringで縁取り文字を描きたい - Qiita](https://qiita.com/AioiLight/items/4f6aa763e2ddfffcf0e3)
- [文字列を縁取りをして描画する - .NET Tips (VB.NET,C#...)](https://dobon.net/vb/dotnet/graphics/drawoutlinestring.html)
- [アンチエイリアス処理をして描画する - .NET Tips (VB.NET,C#...)](https://dobon.net/vb/dotnet/graphics/antialias.html)
- [Graphics.SetClip Method (System.Drawing) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/api/system.drawing.graphics.setclip?view=netframework-4.8)
- [GraphicsPath.AddString Method (System.Drawing.Drawing2D) | Microsoft Docs](https://docs.microsoft.com/en-us/dotnet/api/system.drawing.drawing2d.graphicspath.addstring?view=net-5.0)


# JavaScriptでもやってみた

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="kob58im" data-slug-hash="BaWWLEO" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Partial Draw Text">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/BaWWLEO">
  Partial Draw Text</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


# 参考サイト（JavaScript）
 - [HTML＋JavaScriptだけでブラウザに図形描画（2） - Canvas API - | Think IT（シンクイット）](https://thinkit.co.jp/story/2012/08/06/3637)
 - [合成とクリッピング - Web API | MDN](https://developer.mozilla.org/ja/docs/Web/API/Canvas_API/Tutorial/Compositing#clipping_paths)