ブログに戻る
コミュニティ

PTTで画像リンクが自動展開しない理由をソースコードから検証:4つの異なる判定ルール

公開日25 min read
共有

リンクを貼ったのに画像が開かない――正直、最初は自分のミスだと思っていました

台湾には「PTT」という、20年以上前から稼働し続けている巨大なテキストベースBBS(電子掲示板)があります。telnet接続のターミナル画面を今も使い続けているにもかかわらず、アクティブアカウント数は数百万規模という不思議な存在です。ここに投稿する人なら誰でも一度はぶつかるのが、「画像リンクを貼っても自動でサムネイルになるときとならないときがある」という現象です。

多くの人が最初に混乱するのは、「どのサービスが優れているか」ではありません。まったく同じリンクなのに、スマホアプリでは自動的にサムネイル表示され、パソコンのWebブラウザ版で見ると単なる文字列のURLとして残る――この食い違いです。

これは偶然でも、貼り方のミスでもありません。「PTT」という名前の下には、実は互いに関係のない4種類のソフトウェアが存在していて、それぞれが独自のロジックで「このURLを画像に変換すべきか」を判定しています。拡張子だけを見るもの、ドメインのホワイトリストだけを見るもの、両方を要求するもの。中には拡張子チェックを完全に飛ばして、貼られたのがImgurのリンクだろうと決め打ちしている実装まであります――この話は後ほど詳しく触れます。

PTTの質問板(ask板)に、自動展開に対応する画像ホストは何かを尋ねるスレッドが2025年10月に立っていました。投稿者いわく、以前はterm.ptt.ccでImgurのリンクにマウスを乗せると画像プレビューが浮かび上がったのに、半年ほど前から効かなくなったとのこと。この一文が示しているのは、多くの人が気づいていない事実です。同じクライアント、同じ画像ホストであっても、ルールは時間とともに変わり、しかも誰も告知してくれません。噂話を鵜呑みにするより、主要クライアントのソースコードを自分で読んだほうが早いと考え、実際に読みました。以下の表の一マスひとマスに、根拠となる出典があります。

PTTで画像を見る経路は実質5通り――「PTT」はひとつのソフトではない

比較表を見る前に、まず整理しておきます。

  • テキスト専用のBBSクライアント(PCMan、Wellyなど):文字しか扱わず、画像リンクは常にただの文字列です。
  • www.ptt.cc のWeb版記事:記事ページを読み込む際、サーバー側で条件に合うURLを <img> タグへ変換してから配信します。
  • term.ptt.cc:WebSocketでBBSに接続するWebターミナル。リンクにマウスを乗せるとプレビューが表示され、判定はフロントエンドのJavaScript側で行われます。
  • PttChrome:歴史あるブラウザ経由のtelnetクライアント。画像が記事画面に直接埋め込まれます。
  • スマホアプリ(Mo PTT、JPTT、PiTT、BePTTなど):リンクをサムネイルとして直接表示します。こちらはクローズドソースのため、コミュニティの報告からしか推測できません。

最初の2つと後の3つの間には、想像以上に大きな違いがあります。

ソースコードを実際に読んだ結果――4つのルール、どれひとつ同じではない

www.ptt.cc のWeb版記事:サーバー側判定、拡張子優先、WebPは非対応

www.ptt.cc のWebフロントエンドは pttweb と呼ばれ、ソースコードはGitHubの ptt/pttweb リポジトリで公開されています。記事内のURLを画像に変換する処理を担うのが richcontent/url_based_finder.go で、上から順に照合するパターンのリストが含まれています。

var defaultUrlPatterns = []*UrlPattern{
    newUrlPattern(`^https?://(?:www\.youtube\.com/watch\?(?:.+&)*v=|youtu\.be/)([\w\-]+)`, handleYoutube),
    newUrlPattern(`^https?://i\.imgur\.com/([\w]+)\.((?i)png|jpeg|jpg|gif)$`, handleImgurSingle),
    newUrlPattern(`^http://picmoe\.net/d\.php\?id=(\d+)`, handlePicmoe),
    newUrlPattern(`\.(?i:png|jpeg|jpg|gif)$`, handleGenericImage),
}

重要なのは最後の一行です。最初の3つはYouTube、Imgur、picmoe.net専用のルールで、4番目こそが本命です。どんなドメインであっても、URLの末尾が .png、.jpeg、.jpg、.gif(大文字小文字を区別しない)であれば、一律で <img> タグに変換されます。 つまりwww.ptt.cc のWeb版記事は「拡張子は見るがドメインは見ない」という判定方式で、後述するterm.ptt.ccとはまったく逆の考え方です。

ただし正規表現が $ で終端を固定しているため、URLの末尾がそのまま拡張子でなければなりません。クエリ文字列が付いた xxx.jpg?token=abc123 のような形式は、この最後のルールにヒットしません。さらに .webp はこのリストに一切含まれていません。つまり正真正銘のWebP直リンクであっても、www.ptt.cc のWeb版記事では絶対に自動展開されず、リンクの文字列だけが残ります。この点は他の解説記事ではあまり明確に触れられていません。

term.ptt.cc:ドメインのホワイトリストが第一関門、拡張子は第二関門

term.ptt.ccのソースコードはGitHubの ptt/ptt-term にあり、WebSocketでBBSに接続するWebターミナルです。マウスホバーによるプレビューを担当するモジュールは src/plugins/media_previewer/image_preview_util.js で、デフォルトの信頼ドメインリストがコード内に直接書かれています。

export const INITIAL_TRUSTED_IMAGE_DOMAINS = [
  "imgur.com", "imgtok.com", "meee.com.tw", "duk.tw",
  "upload.cc", "ibb.co", "imgbb.com", "postimg.cc",
  "twimg.com", "gyazo.com",
];

このリストには urusai.cc も vgy.me も lpic.cc も含まれていません。ところが同じask板のスレッドでは、urusai.ccやvgy.meが自動展開できたという報告があります。矛盾しているように見えますが、実はそうではありません。コード内には parseTrustedDomains という関数もあり、このホワイトリストは設定で追加できる仕組みになっています。つまりデフォルトの10件はあくまで「初期状態」であり、全部ではないのです。正直なところ、そのユーザーは自分の設定にurusai.ccを追加済みだった可能性が高く、term.ptt.ccが全ユーザーに対して標準対応しているわけではありません。ここは「全体のルール」だと誤解されやすいポイントです。

判定ロジックは二段階です。Imgurには専用の正規表現があり、拡張子がなくても認識されます。pbs.twimg.com/media/ から始まるリンクは拡張子チェックなしで通過します。それ以外のホワイトリストドメインについては、URLの末尾が .jpg、.jpeg、.png、.gif、.webp、.bmp のいずれかである必要があり(クエリ文字列が付いていても問題ありません、この点はwww.ptt.cc版と異なります)、term.ptt.ccは「ドメイン かつ 拡張子」の両方をクリアする必要がある方式です。

PttChrome:ドメインだけで判定、拡張子は見向きもしない

PttChromeはさらに古いソフトウェアで、現在メンテナンスされているバージョンは iamchucky/PttChrome にあります。画面上の画像プレビューを担当するファイルは js/term_view.js で、対象リンクの選定には次のjQueryセレクタが使われています。

var aNodes = $(".main a[href^='http://ppt.cc/'], .main a[type='p'], " +
  ".main a[href^='http://imgur.com/'], .main a[href^='https://imgur.com/'], " +
  ".main a[href^='https://flic.kr/p/'], .main a[href^='https://www.flickr.com/photos/']")
  .not("a[href^='http://imgur.com/a/'], a[href^='https://imgur.com/a/'], " +
       "a[href^='http://imgur.com/gallery/'], a[href^='https://imgur.com/gallery/']");

ここが厄介なところです。PttChromeは拡張子をまったくチェックせず、URLの先頭部分だけで判定します。ホワイトリストにあるのは ppt.cc の短縮URL、imgur.com(アルバムやgalleryページは除外)、flic.kr、flickr.com/photos のみ。urusai.cc、vgy.me、duk.tw、meee、ImgBB、Postimages、lpic.ccはすべて対象外で、どれだけ標準的な直リンクを貼っても自動展開されず、常にただの青いリンク文字列のままです。さらに興味深いのはImgurリンクの処理方法で、コード内でURLを i.imgur.com/ID.jpg に書き換えており、拡張子を .jpg に固定しています。元画像がPNGやGIFであっても関係ありません。この十数年来のちょっとした癖に普段誰も気づかないのは、Imgurが拡張子の不一致をあまり気にせず正しい画像を返してくれることが多いためです。

スマホアプリ(Mo PTT、JPTT、PiTT):クローズドソースにつき、コミュニティ証言のみ

正直に言うと、この部分だけはソースコードレベルの答えを出せません。Mo PTT、JPTT、PiTTはいずれもクローズドソースの商用アプリで、GitHub上に対応するリポジトリが存在しません。私が見つけられた最も確度の高い証拠は、2025年6月と10月という近い時期に投稿されたPTT ask板の2つのスレッドで、ユーザーが実際に試した結果を報告している内容です。meee.com.twは手動で .jpg を付ければ自動展開できる、urusai.ccの i.urusai.cc/ID.png 形式は展開できる、imgpoi.comは「そもそも自動展開に対応していないのでは」と疑問視されている、といった具合です。これらはいずれも「拡張子で判定している」方向を示唆しており、www.ptt.cc のWeb版のロジックに近いと考えられますが、これらのアプリのソースコードや公式技術文書を提示してドメイン制限の有無まで実証した人はいません。この項目は明確に未検証として扱います。自分でコードを解析したかのように装うつもりはありません。

4つのルールをまとめて比較

クライアント 判定基準 拡張子の要件 WebP 証拠レベル
www.ptt.cc Web版記事 拡張子のみ、ドメインは見ない 末尾が .jpg/.jpeg/.png/.gif であること、クエリ文字列不可 非対応 ソースコード(ptt/pttweb)
term.ptt.cc ドメインホワイトリスト+拡張子の両方 ホワイトリスト内ドメインで末尾が .jpg/.jpeg/.png/.gif/.webp/.bmp、クエリ文字列は可 対応 ソースコード(ptt/ptt-term)
PttChrome ドメインのみ、拡張子は未チェック チェックなし(Imgurリンクは強制的に.jpgへ書き換え) 該当なし ソースコード(iamchucky/PttChrome)
スマホアプリ(Mo PTT/JPTT/PiTT) 拡張子判定と推測される .jpg/.png/.gif で動作したとの報告あり 未検証 コミュニティ報告のみ、ソース未確認

表を並べてみると分かる通り、「PTT共通のルール」というものは存在しません。 同じ画像ホストの直リンクでも、4種類のクライアントで4通りの結果になり得ます。

日本のコミュニティに置き換えると、5chの画像貼り付け文化やQiitaの埋め込みプレビュー、pixivのサムネイル表示などもそれぞれ独自の判定ロジックを持っていて、統一されているわけではありません。PTTのケースが特殊というより、掲示板文化そのものが「各クライアントが好き勝手にルールを実装する」歴史を持っている、と捉えるほうが実態に近いでしょう。

画像ホスト × クライアント 対応表

上記のルールと、よく使われる画像ホストの直リンク形式を照合して作成した表です。「✅」はルール上自動展開されるはず、「❌」は展開されない、「⚠️」は設定や拡張子の手動調整次第、を意味します。

画像ホスト(直リンク例) www.ptt.cc Web版 term.ptt.cc(初期設定) PttChrome アプリ(コミュニティ報告)
Imgur i.imgur.com/ID.jpg ✅ ✅ ✅(強制的に.jpgへ変換) ✅
meee meee.com.tw/ID.jpg ✅ ✅ ❌ ✅(手動で拡張子を付ける必要あり)
duk.tw ✅(拡張子付きなら) ✅ ❌ 未検証
urusai.cc i.urusai.cc/ID.png ✅(拡張子付きなら) ⚠️ 自分でホワイトリストに追加が必要 ❌ ✅(コミュニティ報告)
vgy.me ✅(拡張子付きなら) ⚠️ 自分でホワイトリストに追加が必要 ❌ 未検証、コミュニティでは「一番厄介」との声
ImgBB ibb.co / i.ibb.co ✅(拡張子付きなら) ✅ ❌ 未検証
Postimages postimg.cc ✅(拡張子付きなら) ✅ ❌ 未検証
lpic.cc lpic.cc/{code} ❌(拡張子なし) ❌(ホワイトリスト外、拡張子もなし) ❌ ❌(直リンクが存在しない)

最後の行については、包み隠さず説明しておきます。

lpic.ccのリンクは今PTTで自動展開できるのか――結論、できません

この記事を書くにあたって、lpic.cc 自体の共有リンクの形式を改めて確認しました。現在アップロード後に得られるのは https://lpic.cc/{ショートコード} という作品ページへのリンクであり、i.imgur.com/xxx.jpg のように末尾が画像の拡張子で終わる直リンクではありません。そのため、www.ptt.cc の拡張子ルールも、term.ptt.ccやPttChromeのドメインホワイトリストも、どれも該当しません。共有ページ自体はサムネイルを表示しますが、それはページを開いたときに見えるものであって、「リンクを貼った瞬間に自動展開される」ものではないのです。

正直なところ、自動展開を目的にしている人にとっては朗報とは言えません。取り繕うつもりはありません。「リンクを貼るだけでアプリが自動的にサムネイル化してくれる」ことを求めているなら、上の表で✅が付いた画像ホスト(Imgur、meee、term.ptt.ccの初期ホワイトリストに含まれるサービスなど)のほうが向いています。lpic.ccのような共有ページ型の強みは別のところにあります。パスワード保護、閲覧回数、コメント欄といったページ上の機能は、「誰が見たか」「見た記録を残すか残さないか」を自分でコントロールしたい場面、たとえば取引画面のスクリーンショットや、あまり多くの人に自動で見られたくないコンテンツに向いています。この2つのニーズはそもそも別物で、片方の道具にもう片方の役割を無理にやらせても、使い心地は良くなりません。

結局どれを選べばいいのか

「貼った瞬間にとにかく自動展開してほしい」だけなら、主に使っているクライアントで判断してください。スマホアプリ中心ならImgur、または拡張子を手動で付ける習慣があるならmeeeが向いています。Web版記事の閲覧が中心なら、標準的な拡張子の直リンクを持つ画像ホストならおおむね対応しますが、WebPだけはwww.ptt.ccのWeb版記事では通用しないことを覚えておいてください。term.ptt.ccを使うなら、まず自分のホワイトリスト設定にその画像ホストが入っているかを確認し、入っていなければ手動で追加してください。

複数のクライアントで横断的に使えるものが欲しいなら、4つのルールすべてに対応しているのは今のところImgurだけです。ただし代償として、台湾のIPアドレスからのアップロードがブロックされているという別の問題があります。この点についてはPTT画像投稿の完全ガイドでさらに詳しくまとめています。あらゆる場面でフォーマットの心配をゼロにしてくれる画像ホストは、正直なところ存在しません。何度も痛い目に遭ってきたからこそ、特定のサービスを持ち上げるようなことはしません。

よくある質問

Q1:昨日は自動展開できたImgurのリンクが、今日はできなくなりました。なぜですか?

Imgurは2025年5月から台湾のIPアドレスをブロックしています。台湾国内から閲覧している場合、そもそもi.imgur.com自体に接続できていない可能性があり、これはPTTクライアント側のルールとは無関係です。また、PttChromeはImgurリンクを強制的に .jpg へ書き換えるため、元画像が透明背景のPNGだった場合は画質や透明度が損なわれることがあります。ただしこれは表示品質の問題であり、「開けるか開けないか」自体には影響しません。

Q2:term.ptt.ccの信頼ドメインリストは自分で編集できますか?

ソースコードを見る限り、parseTrustedDomains という関数がカスタムリストの読み込みに対応しているため、これは調整可能な設定であり、書き換え不可能な固定ルールではありません。ただし、実際にどの操作画面から設定するのか、変更後にページの再読み込みが必要かどうかまでは実機で確認できていないため、term.ptt.ccの設定メニューを直接確認することをおすすめします。

Q3:スマホアプリがドメインホワイトリストを見ているかどうか、なぜ断定できないのですか?

Mo PTT、JPTT、PiTTはいずれもクローズドソースで、公開されているリポジトリを一行ずつ確認する手段がないためです。この記事内でこれら3つのアプリについて書いている内容は、すべてPTT ask板のユーザー報告に基づくものであり、自分でアプリを解析して得た結論ではありません。前述の通り未検証と明記しており、ここで急に確定情報であるかのように扱うことはしません。

Q4:なぜwww.ptt.ccはWebPに対応していないのに、term.ptt.ccは対応しているのですか?

この2つはまったく独立したコードベースだからです。片方はサーバー側のGoで書かれたpttweb、もう片方はフロントエンドのJavaScriptで書かれたptt-termで、開発者も開発時期も異なります。WebP形式が普及したのは比較的後の話で、pttweb側のルールが単純に追随していないだけです。まさにこの記事で伝えたかった核心はここにあります。PTTはひとつの統一されたシステムではなく、複数の独立したソフトウェアが寄せ集まって成り立っているエコシステムなのです。

Q5:すべてのPTTクライアントで自動展開できるリンクの組み合わせ方は?

すべての状況に対応できる単一のリンクは存在しませんが、最も近づける方法はあります。画像ホストの直リンクの末尾を標準的な拡張子(.jpg/.png/.gif、WebP単体には頼らない)にすること、クエリ文字列を付けないこと、そしてterm.ptt.ccの初期ホワイトリストに含まれる画像ホスト(Imgur、meee、duk.tw、ImgBB、Postimagesなど)を優先することです。PttChromeユーザーには選択肢がほとんどなく、現状ImgurとFlickr程度しか対応していません。

参考資料

#PTT#term.ptt.cc#PttChrome#画像ホスティング#自動サムネイル展開#直リンク#掲示板 画像投稿#BBS 台湾
A

著者

Alex Chen

製品テスター

すべてのツールを実際に使用し、一人称で本物の使用体験をお届けします。