Xに上がったイラストは出どころの記録が0.1%しか残らない【49,649枚を実測】

AI・自動化
スポンサーリンク

X に上がったイラストは、出どころの記録が0.1%しか残っていませんでした(49,649枚を読んで数えました)

わたくしは Fudemark という、手描きのイラストと AI のイラストの棲み分けを手伝うスコアツールの運営をしています。そこで「SNS に上がった画像は、ファイルを読んでも出どころが分からなくなります」と説明してきました。言っている本人が数えていなかったので、数えました。

結論を先に書きます。

  • X から拾われたイラスト 23,809枚のうち、出どころの記録が残っていたのは12枚(0.1%)
  • pixiv から拾われたイラスト 17,008枚のうちは、4,965枚(29.2%)

同じ時期に、同じ投稿サイトへ集まった絵です。描いた人の層も、使っている道具もほぼ同じでした。違うのはどこを通ってきたかだけです。

スポンサーリンク

配信をしている方に関係のあるところ

立ち絵、サムネイル、エモート、配信画面の素材。絵を依頼して受け取ることが多い仕事だと思います。

そこで時々起きるのが、「あれは AI で描いたものではありませんか」という問いかけです。受け取ったファイルを開いて確かめようとしても、X から保存した画像ならまず何も入っていません。確かめ方が悪いわけではありません。X を通った時点で、中身が落ちています。

逆の向きでも困ります。ご自分で描いて X に上げた絵は、その先どこへ流れても、あなたの道具の記録を持っていきません。無断転載を見つけた時、ファイルの中身が味方になってくれない状態です。

何を測ったのか

イラストの投稿サイト Danbooru には、「この絵をどこで拾ってきたか」を投稿者が書く欄があります。保存されているのは原寸のファイルです。つまり同じ母集団を、通ってきた経路で割って比べられます。ここが今回の肝でした。

  • 対象: 2026年以降に投稿された、AI のタグが付いていないイラスト 49,649枚
  • 読んだもの: C2PA の署名、制作ソフトの記録、カメラの機種とメーカー、撮影日時、XMP、解像度
  • 画像そのものは保存していません。読んだ値だけを残して、ファイルは捨てています
  • 比べる相手として、AI で生成した絵・写真・手元の原本も読みました。合計 66,209枚 になりました

「出どころの記録がある」の数え方は、二段にしてあります。甘い方だけを出すと話を良くしすぎてしまいますので、両方を見ています。

  • 出どころ: C2PA の署名/制作ソフトの名前/カメラの機種・メーカー/撮影日時。誰の何から出てきたかが分かるもの
  • 何かしら: 上に加えて、解像度の欄だけ・XMP だけ。記録の欄が空ではない、という程度のもの

この記事の数字は、きびしい方(出どころ)です。甘い方で数えると 49,649枚のうち 7,767枚(15.6%)になりました。

経路ごとの残り方

拾われた場所枚数出どころの記録率JPEG の割合平均の大きさ
x.com23,809120.1%96.9%603 KB
pixiv (i.pximg.net)17,0084,96529.2%55.9%3,717 KB
小紅書7368010.9%54.1%3,626 KB
twitter.com71720.3%95.7%634 KB
bilibili66512719.1%70.5%4,560 KB
Bluesky55810.2%97.7%1,063 KB
Weibo23600.0%99.6%3,136 KB
DeviantArt2106932.9%59.5%1,265 KB
Instagram10800.0%84.3%373 KB
misskey.io571933.3%3.5%766 KB
Skeb5211.9%28.8%372 KB

全体では、49,649枚のうち 6,162枚(12.4%)でした。経路を分けないと、この 12.4% という平均の中に「0.1% の道」と「29.2% の道」が混ざって見えなくなります。

X が通した絵がいちばん多く、そこがいちばん何も残っていませんでした。出回っている絵のうち、最大の流れが記録を落としているということだと思います。

Skeb の 1.9% だけ、ひとつお断りがあります。公開ページに出ている画像は納品されたファイルそのものではありませんので、この行は「納品物にも記録が無い」という意味にはなりません。

なぜ消えるのか

右端の2列が答えでした。

  • X を通った絵は 96.9% が JPEG、平均 603 KB
  • pixiv を通った絵は JPEG が 55.9%、平均 3,717 KB(6倍)

X は受け取った画像を JPEG に作り直しています。作り直せば、中に書かれていた文字の欄は付いてきません。pixiv は上げたファイルをそのまま配っているので、書かれていたものがそのまま残ります。

もうひとつ、おもしろいことがありました。X 経由で記録が残っていた12枚を1枚ずつ見ると、11枚が PNG でした。中身は CLIP STUDIO PAINT が7枚、Photoshop が3枚、GIMP が1枚です。JPEG で記録が残っていたのは1枚だけでした。作り直されなかったものだけが生き残っています。

業界の正式な印は、まだ助けになりません

出どころを証明するための規格として、C2PA というものがあります。ファイルの中に「誰が作ったか」を署名付きで入れる仕組みです。Adobe や Microsoft が入っている、きちんとした取り組みです。

66,209枚のうち、C2PA が付いていたのは 664枚 でした。中身を分けると、こうなりました。

C2PA が言っていること件数割合
AI が作った、と言っている61993.2%
人が使う道具(Photoshop・Lightroom など)71.1%
どちらとも書いていない385.7%

書き込んだ道具の内訳は、OpenAI が457件、ChatGPT が66件、Google が47件、Grok が19件。並べてみると、ほとんどが生成サービスでした。

そして、2026年以降に投稿されたイラスト 49,649枚のうち、C2PA が付いていたのは9枚です。そのうち7枚が Adobe の道具、2枚が OpenAI でした。

ここが今回いちばん意外だったところです。C2PA は「これは本物です」の印として作られた規格だと思っていました。けれど実際に出回っているファイルの中では、今のところ「これは AI が作りました」の印として広まっています。手描きの側は、まだほとんど署名していません。

「標準規格に乗れば解決します」と考えていたのですけれど、乗る相手が手描きの側には、まだ存在していませんでした。

実際に残っていたのは CLIP STUDIO PAINT でした

では、記録が残っている 6,162枚には何が書かれていたのか。数えると、答えは規格ではありませんでした。

残っていた制作ソフトの記録件数49,649枚に対して
CLIP STUDIO PAINT4,8779.8%
Photoshop(Web 用に保存)3060.6%
Adobe Photoshop CS5.1 Windows890.2%
Adobe Photoshop CC 2019 (Windows)870.2%
Adobe Photoshop CS6 (Windows)670.1%

出回っているイラストに残っている記録の中で、いちばん多いのは CLIP STUDIO PAINT でした。署名でも証明書でもなく、書き出しの時に黙って入る1行の文字です。それが今のところ、いちばん広く残っている「出どころ」でした。

反対に、手元の原本も読んでみました。タブレットのお絵描きアプリ(ibisPaint)で描いた原本 35枚は、1枚も記録を持っていませんでした。書き出した直後の原本で、何も入っていない状態です。描く道具によっては、原本からして空です。

写真はまったく違いました。スマートフォンとカメラで撮った 408枚は、408枚すべてに記録が残っていました(100%)。カメラが必ず書き込むからです。絵だけが裸でいます。

ご自分で確かめる

150枚だけ読む短いものを書いて、動かしました。Python と Pillow だけで動きます。画像は読んだらすぐ捨てますので、手元には残りません。

"""Count how many circulating illustrations still carry a record of where they came from,
grouped by the platform they were taken from. Images are read and thrown away, never stored.

    python where_did_it_go.py 200
"""
importcollections,io,sys,time,urllib.parse,urllib.request
fromPILimport Image

UA = {"User-Agent": "metadata-survival-check/0.1 (non-commercial research)"}
API = "https://danbooru.donmai.us/posts.json?"


defget(url, binary=False):
    for i in range(3):
        try:
            with urllib.request.urlopen(urllib.request.Request(url, headers=UA), timeout=120) as r:
                return r.read() if binary else r.read().decode("utf-8")
        except Exception:
            if i == 2:
                return None
            time.sleep(5 * (i + 1))


deforigin_record(data):
   """Does the file say which tool or camera produced it?"""
    try:
        im = Image.open(io.BytesIO(data))
    except Exception:
        return None
    tool = im.info.get("Software") or ""
    for key in ("parameters", "Comment", "Description"):          # PNG text chunks
        tool = tool or (im.info.get(key) or "")[:40]
    exif = {}
    try:
        exif = {k: v for k, v in (im.getexif() or {}).items()}
    except Exception:
        pass
    has_c2pa = b"jumb" in data[:65536] or b"c2pa" in data[:65536]
    camera = exif.get(271) or exif.get(272)                        # Make / Model
    software = exif.get(305) or tool                               # Software
    return {"fmt": im.format, "kb": len(data) // 1024,
            "found": bool(has_c2pa or camera or software),
            "what": str(software or camera or ("C2PA" if has_c2pa else ""))[:34]}


defmain(want=200):
    importjson
    seen, page, rows = 0, None, []
    while seen < want:
        q = {"tags": "date:>=2026-01-01", "limit": 100}
        if page:
            q["page"] = page
        posts = json.loads(get(API + urllib.parse.urlencode(q)) or "[]")
        if not posts:
            break
        page = f"b{min(p['id']forpinposts)}"
        for p in posts:
            if seen >= want or p.get("rating") not in ("g", "s") or not p.get("file_url"):
                continue
            data = get(p["file_url"], binary=True)
            if not data:
                continue
            got = origin_record(data)
            del data
            if not got:
                continue
            seen += 1
            rows.append((urllib.parse.urlparse(p.get("source") or "").netloc.lower() or "(none)", got))
            time.sleep(0.5)

    by = collections.defaultdict(list)
    for dom, got in rows:
        by[dom].append(got)
    print(f"\n{'taken from':26}{'n':>5}{'has record':>11}{'rate':>7}{'JPEG':>6}{'avg KB':>7}")
    for dom, gs in sorted(by.items(), key=lambda kv: -len(kv[1])):
        f = sum(g["found"] for g in gs)
        j = sum(g["fmt"] == "JPEG" for g in gs)
        print(f"{dom:26}{len(gs):5}{f:11}{f/len(gs)*100:6.1f}%{j/len(gs)*100:5.0f}% "
              f"{sum(g['kb']forgings)/len(gs):7,.0f}")
    total = sum(g["found"] for gs in by.values() for g in gs)
    print(f"\n{'TOTAL':26}{len(rows):5}{total:11}{total/max(len(rows),1)*100:6.1f}%")


if __name__ == "__main__":
    main(int(sys.argv[1]) if len(sys.argv) > 1 else 200)

150枚で動かした結果が、こちらです。

taken from                     n  has record    rate   JPEG  avg KB
x.com                         82           0    0.0%    96%     580
i.pximg.net                   47          14   29.8%    53%   4,182
www.xiaohongshu.com            4           0    0.0%    75%   1,620
www.weibo.com                  3           0    0.0%   100%     722
www.bilibili.com               2           0    0.0%     0%   1,358
bsky.app                       1           0    0.0%   100%   1,775

TOTAL                        150          17   11.3%

150枚でも、pixiv が 29.8%、X が 0.0% でした。49,649枚で出た 29.2% と 0.1% と、ほぼ同じ数字です。わたくしの手元の見本がおかしい、という話ではなさそうです。お手元で動かしても、同じくらいの数字が出ると思います。

提案(依頼する側・描く側)

絵を依頼して受け取る側へ。 納品は、SNS を通さない道で受け取っておくのがよいと思います。ファイル転送サービス、クラウドの共有、pixiv のメッセージなど、作り直されない道です。X の画像を右クリックで保存したものを原本として持っておくと、0.1% の側に入ります。あとから「これは誰が描いたのか」を確かめたくなった時、手元に何も残っていません。

ご自分で描いて上げる側へ。 PNG で書き出すと、制作ソフトの記録が付いてきます(CLIP STUDIO PAINT は入ります)。X に上げる分は作り直されてしまいますので、原本の置き場所を X の外にもう一つ持つ形が現実的だと思います。pixiv・個人のサイト・自分のクラウド。流通用と原本用を分けておく、という考え方です。

確かめようとしている側へ。 SNS に流れている画像から、ファイルの中身だけで手描きか AI かを決めるのは、無理だと思います。そこに記録が無いのは、描いた人の都合ではありません。通ってきた道の都合です。記録が無いことを、怪しさの証拠にしないでください。 23,809枚のうち 23,797枚が、その状態です。

この数字で言えないこと

  • Danbooru の「どこで拾ったか」は、投稿した人が書いた欄です。間違いも、書かれていないものもあります(670枚は空欄でした)
  • 「記録が無い」は「AI が描いた」という意味になりません。X を通れば、手描きでも消えます。この記事はそれを数えたものです
  • 投稿した人が、保存したあとで自分で作り直している場合もあります。経路の影響と、その影響を分けて数えることはできていません
  • 対象は Danbooru に集まる種類の絵です。すべてのイラストの話として読むには、偏りがあります

数え方のきびしい方・甘い方の両方を出したのは、こちらに都合のよい方だけを見せたくなかったからです。もし別の数え方をなさるなら、上のコードの origin_record を書き替えるところになります。

わたくしは Fudemark で、送られてきた画像の記録を読んでスコアを出しています。50 という数字は「判定できません」の意味で、今回数えたとおり、X を通った絵は、そこに集まってしまいました。道具を良くしても、記録が無いものは読めません。 そこは正直に書いておきます。

辛子屋 芥子

コメント

タイトルとURLをコピーしました