これなに?

ブラウザからローカルのサーバーにアクセスさせて「http:/localost:8085/キャラ名/表情名]みたいなURLに対応する画像を返すスクリプト。
つまりローカルHTTPサーバー。50行弱のbatファイル1個で完結してるので安心。(※Windows専用)
でも自己責任で使ってください。

[bat本体]

(UTF-8で保存するべし。名前はなんでもいいけど「StartServer.bat」とか)

/** > nul 2>&1
@echo off
@SET PS_SCRIPT= Add-Type -TypeDefinition (Get-Content -Encoding UTF8 -Path '%~f0' -Raw) -ReferencedAssemblies @('System.Runtime.dll','System.Web.dll','System.Web.Extensions.dll'); [EasyFaceHTTPServer]::Main(0);
powershell.exe -noprofile -executionpolicy bypass -command "%PS_SCRIPT%"
pause */
using System;using System.IO;using System.Net;using System.Web;using System.Linq;
using System.Diagnostics;using System.Threading.Tasks;using System.Collections.Generic;
public class EasyFaceHTTPServer {
    const string FACEIMG_DIR = "faces";                 // キャラ顔画像があるフォルダ名(相対パス)
    const string FACEIMG_DEFAULT = "普通";                // 表情差分がなかった場合のファイル名(拡張子なし)
    const string FACEIMG_NOTFOUND = "not_found.jpg";    // パスが不正な場合に返す画像のファイル名
    const string URL = "http://localhost:8085/";        // ポート番号を変えたいならここを編集

    public static void Main(string[] args) {
        var listener = new HttpListener();
        listener.Prefixes.Add(URL);
        listener.Start();
        Console.WriteLine("\n【このプロンプトウィンドウを閉じればローカルサーバー終了】\n => ["+ URL+"]でローカルサーバーが待機中");
        while (true) {// リクエストがあるまで停止あれば非同期で処理
            HttpListenerContext ctx = listener.GetContext();
            Task.Run(async () => {
                try {
                    string decodedPath = HttpUtility.UrlDecode(ctx.Request.Url.LocalPath.TrimStart('/'));
                    string dirChar = Path.GetFullPath(Path.GetDirectoryName(Path.Combine(FACEIMG_DIR, decodedPath)));
                    string emotion = Path.GetFileNameWithoutExtension(decodedPath);
                    string filePath = null;
                    if (dirChar.StartsWith(Path.GetFullPath(FACEIMG_DIR)) && Directory.Exists(dirChar)) {
                        filePath = Directory.GetFiles(dirChar, emotion + ".*").FirstOrDefault()
                                ?? Directory.GetFiles(dirChar, FACEIMG_DEFAULT + ".*").FirstOrDefault();
                    }
                    filePath = filePath ?? Path.GetFullPath(Path.Combine(FACEIMG_DIR, FACEIMG_NOTFOUND));
                    Console.WriteLine(" request:" + decodedPath + "\n   ->" + filePath);
                    byte[] buffer = await Task.Run(() => File.ReadAllBytes(filePath));
                    ctx.Response.ContentType = MimeMapping.GetMimeMapping(filePath);
                    ctx.Response.ContentLength64 = buffer.Length;
                    await ctx.Response.OutputStream.WriteAsync(buffer, 0, buffer.Length);
                } catch { ctx.Response.StatusCode = 500;} finally { ctx.Response.OutputStream.Close();}
            });
        }
    }
}

使い方

[ざっくり]

  1. 上のbatをUTF-8で保存
  2. フォルダとか画像を準備
  3. batファイルを起動(これでサーバー起動)
  4. コマンドプロンプトを終了すれば終了

[もうちょっと詳しく]
上の中身のbatファイルを作って起動する。UTF-8のテキストファイルとして保存しないとbatは正常に動かない。
batの中身がサーバーになっているのでbat起動したらローカルサーバーが起動される。
コマンドプロンプト落としたらサーバー停止。コードは中を見てね50行くらいなので。
(中身はC#スクリプトでHTTPサーバー立ててリクエストに対応した画像を返してるだけ)

起動している間はローカルサーバーとしてブラウザからリクエストあれば画像を返す。
閉じたらサーバーも終わり。閉じてると当然画像も返らない。つまり使う時だけ起動しておく。

作者はwin11でしかテストしてないのでwin10とかはわかりません。
エラー出てもC#わかる人なら手直しすれば動くようにできると思う。

準備

batファイルを置いたフォルダに「faces」フォルダを作り、
「faces」の下にキャラ名フォルダを作ってその中に表情差分を置く。
「faces」の直下に「not_found.jpg」を置いておけば該当画像がないときはそれが返る。

StartServer.bat
┗faces
 ┣not_found.jpg
 ┣エルフ
 ┃┣普通.png
 ┃┣照れ.png
 ┃┗笑み.png
 ┗おっさん
  ┣普通.png
  ┣照れ.png
  ┗笑み.png

みたいな感じでファイルを配置
透過が使えるpngがいいと思う
フォルダがあって表情がない場合は「普通」が選ばれる

前提知識

・マークダウン記法が使えるLLMチャットサイトで使う。作者はパープレでしか確かめてないけど。
・マークダウンの画像表示の記法は、

![画像が出ないときの代替文字](http://うんたらURL "画像のタイトル")

である。
 LLMにお願いして、キャラ画像を表示させたい部分に上記の画像記法を使ってねと命令する。
 つまり「うんたらURL」の部分を「キャラ名/表情名」とするように指示する。

プロンプトのサンプル(てきとー)

## 指定キャラクター台詞のフォーマット
* 指定された特別なキャラクターの台詞の前には画像を表示し指定キャラクターの台詞は「」ではなく">"を使った引用の形式にする
画像は下記のマークダウン記法を使ったフォーマットを用いる
"![C](http://localhost:8085/{キャラ名}/{感情} "画像")"


![C](http://localhost:8085/謎の男/怒り "画像")
>これがキャラクターの台詞です

* URL内の"{感情}"には下記のリストからそのときのキャラクターの感情に応じて選択される

[普通],[笑み],[困る],[焦り],[照れ],[怒り],[快感],[苦悶]

* URL内の"{キャラ名}"は別途指定とする

## 登場人物
* リック
主人公一人称は」。主人公の一人称で地の文は書かれる
旅の戦士で仲間のエルフ娘と旅をしているエルフ娘とは身体の関係

* リーシャ
まだ若いエルフ主人公の旅の仲間主人公と身体の関係になってから主人公にぞっこんで常にべたべたしてくる

## 画像を用いる指定キャラクター
リーシャを指定キャラクターとするURLのキャラ名は[エルフ]とする
Edit Report
Pub: 14 Mar 2025 03:26 UTC
Edit: 14 Mar 2025 04:56 UTC
Views: 1681