初めての方はこちら

Last-modified: 2024-05-03 (金) 20:47:02

このwikiは
「AIに絵を描いてもらって適当に貼って適当に雑談するスレ」に出入りしている人向けです。
一般的とは言い難いエッチだったり過激な表現が数多くありますので苦手な方は見ない方がいいと思います。

※ちなみにこのwikiはプログラミングとか詳しくない人が書いてます。間違いがある可能性有※
※また編集時の情報と最新verでは情報が異なる可能性があるよ※
みんなで編集してね

テンプレだよ

AIに絵を描いてもらって適当に貼って適当に雑談するスレ

性器描写は要修正・絵師が滅びますぞーやAIと絵描きの問題については単純に荒らしなので黙delでお願いします

◇ 登録不要でお試し可能
https://dezgo.com/

◇ 人工知能板 - http://dec.2chan.net/85/futaba.php?mode=cat

◇ としあきdiffusion Wiki - https://wikiwiki.jp/sd_toshiaki/
◇ 最近のできごと - https://wikiwiki.jp/sd_toshiaki/-s/18780c25
◇ AI絵導入ガイド - https://wikiwiki.jp/sd_toshiaki/-s/0dd28e00#tools_guide
◇ WEBサービスリンク集 - https://wikiwiki.jp/sd_toshiaki/-s/8ef2353c

これからAI絵を始めたい人向け・ツール選び

ツールを選ぼう!

画像を生成する手段は大きく分けて「PCにインストールするアプリ(ローカル環境)」「webサービス(オンライン環境)」の2種類。
前者は基本的にそこそこ良いNVIDIA製GPUのグラボを挿したデスクトップPCが前提、後者はスペックが低いPCやスマホでもwebブラウザやスマホアプリからの利用が可能。
(生成速度が遅くても我慢できるならば、AMD製GPUやCPU処理生成できるソフトもあるにはある)

ツール選び(クリックで拡大できます)

それぞれのページに飛ぶと、もう少し詳しい説明があるよ。

ローカル環境

ローカルPC上でグラボを使って画像生成させる方法。
生成エンジンであるStable Diffusion(SD)は共通で、SDに対して描画指示を出すユーザーインターフェース(UI)を選ぶことになる。
web配布物や自作による学習データ(LoRA等)の追加が可能で、版権キャラクターもすけべな絵も電気代だけで好きなだけ出力できる。
PCスペックに不安がないのであれば基本これの導入一択。
どれもCPU(とメモリ16GB~)で動く設定は可能だがおニューCPUでも世間の100倍くらい遅く、実質不可な処理も多々。グラボなしマイPCで長年戦ってきた古強者限定。

  • Stable Diffusion AUTOMATIC1111 WebUI (推奨) →ローカル版導入
    • A1111 WebUIやSD WebUIと略されることもある(by AUTOMATIC1111氏)
    • 最も利用者が多いゆえに出回っている情報も多く、プラグインで追加できる機能も多数ある。この2点が強み。
    • 導入難易度はそこそこ。手順に従って「Python 3.10」「Git」「1111」の3つを順番に導入する形。
    • Radeon民で「1111を導入したいよん」という人はDirectML版をドウゾ →Radeonで1111
    • 導入難易度は後述のNMKDより高いが、導入に成功すれば豊富な機能が利用可能になる。
  • ワンタッチ版1111 →ワンタッチ版1111の導入
    • 有志(個人)がローカル版1111の導入をかなり簡単にして配布しているもの。
      ハードルをだいぶ下げてくれている。PCに不慣れな人にオススメ。
    • 導入さえしてしまえば、操作や機能における1111との差異はかなり少ない。
    • 基本的に1111の拡張機能も利用できるが、一部例外あり。
  • ComfyUIComfyUI
    • 点在する処理内容(ノード)を線で繋いで作るフローチャートにより、処理内容を視覚的に理解して描画命令を出せる。独特のUIが特徴。
    • SDXL系のモデルを扱う際、「1111のv1.5.xよりも省VRAMで画像生成できる」ことから、ComfyUIを試すAI絵あきもいる。
    • 起動が高速なのもウリのひとつ。
  • NMKD →NMKDの導入
    • 導入がワンタッチ版並みに簡便であることと、RadeonやCPUでの画像生成にも対応しているのが特長。
      とはいえCPUでの画像生成はかなり遅いので厳しいけど…。
    • Radeon民にとっては手軽に導入できる有力候補の一つ。
  • Forge  (SDXLを用いて作成するなら推奨だが注意点あり)  →Forgeの導入
    • 上述のStable Diffusion AUTOMATIC1111 WebUIを最適化することで高速化を図ったアプリでUIはA1111とほぼ同等。A1111からの乗り換えもやりやすい。
      • 特にSDXL系モデルを利用する際のグラボのハードルが下がることや、低スペックのグラボほど高速化の恩恵が大きい。
    • ただし、「A1111が最適化され、Forge利用と遜色ない性能が発揮されるようになった際には、A1111の拡張機能に戻る」とされているため、最終的には使えなくなることが念頭にあり、将来的には別の環境に移行することも考慮しておく必要がある
      • 特に初回の環境としてForgeを選ぶ場合、最終的には別環境を導入しなければならないことを踏まえ、環境が似ているA1111も併せて導入しておくことをお勧めする(上記導入リンク先においてもA1111の設定をそのまま共有する方法が記載されている)。

他にもFooocus、StableSwarmUIなど

Webサービス

基本的には企業が運営するサービス。
有料、または無料でも課金すると条件が良くなるので、グラボやゲーミングPCの価格と比較して考えて欲しい。
複雑なインストールや設定は不要でPCスペックは問わず、スマホ用アプリが用意されているサービスもあるため、初心者にも優しい。
出力できる枚数や内容などにはそれぞれ独自の制限がある。
利用者が多い時間帯は順番待ちが発生する事も。

特に現在高性能PCを持っておらず、画像生成のためにPCを購入しようか考えている場合は、まず有料サービスを利用した上でどのようなものかをよく知った上で購入することをお勧めする。

  • NovelAI(有料) (オススメ) →NovelAI
    • 通称「NAI」。月額制有料クラウドサービスの一つ。ブラウザ上から利用できる。UI設定に日本語あり
    • 2022年10月頃に美麗なAIイラストが生成できることで一躍話題となり、画像生成AIの知名度を大きく引き上げるきっかけとなった。
      • ローカル環境が充実するにつれ、あくまで流行のきっかけであるが触れる必要もないとされていたが、2023年11月に更新されたV3で性能が大きく向上し、SDXLの学習が未だ道半ばであることも相まって、ローカル環境以上の品質の画像が出せることで再度利用者が増えている状況。
    • danbooruに絵が多いキャラクターは普通に出るが、LoRAが使えないため自由度は低い。また、NSFW、つまりエッチなイラストも普通に規制なしで出すことができるのも強み。
      • 単純にイラストを生成したいだけであれば2024年3月現在人気のSDXLモデル以上の品質のものが出せるので、とりあえず現在の画像生成AIがどのようなものかを知りたいならば好適。
    • SD(SDXL)をベースに独自改良されており、プロンプトの記述形式も若干SDとは異なる。
    • 値段は最低月額10ドルであり無料で利用することはできない点に注意。
  • Bing イメージクリエーター (無料) →Bing Image Creator
    • Microsoftの運営するAI画像生成サービス。
    • 日本語でのプロンプト入力も可能で、大企業パワーにより高品質な画像を簡単に作ることができる。
    • ただしすけべやセンシティブな規制はガチガチ。
    • 初音ミク、マリオ、セーラームーンといったごく一部の版権キャラクターは出るが、それ以外は無理。
    • 生成エンジンはSDではなくDALL-E (2023年11月時点ではDALL-E3)。
  • Stable Diffusionをwebで使えるサービス →SD Webサービス
    • いくつもあるので詳しくはリンク先を参照
    • スレで利用者が多いのはPixAI、SeaArt (基本無料、課金可能)
    • プロンプト記述やモデル・LoRAらはローカル環境と共通なので、そこらでお試しで遊んでみてからグラボやPCを買っても良い。

レンタルGPUサービス

前述のPC用アプリをGPUつよつよサーバーにインストールして使う方法。
「クラウドスペースを借りて、そこで1111を動かそうぜ!」みたいな。
PCスペックに自信の無い人でもローカル環境とおおむね同等の機能が使えるが、PCやサーバー知識がある程度必要になる。
またGPUは複数ユーザーで共有するため、あまりに長時間 高い負荷をかけ続けたりすると警告を受ける

  • Google Colab Pro(有料) →Colab版導入
    • あまりにも負荷が高かったようで、無料版での利用は禁止されてしまった
  • Paperspace →Paperspace版導入

もっと詳しく教えて!

誘導→よくある質問#tool_selection

 

(としあき製)スレ閲覧時に便利なブックマークレット

画像の埋め込み情報を表示

まずは新しいブックマークを適当に作成し、そのURLを下記のいずれかの内容に書き換えて保存してください。

2024/4/24版

2024/4/24版
3/15版を、デフォルトで開いてある仕様に変更したもの

javascript:(()=>{let dlst=["masterpiece","best quality","score_\\d+(_up)?","lowres","bad (anatomy|hands)","text","error","missing fingers","(extra|fewer) digits?","cropped","(worst|low|normal) quality","jpeg artifacts","signature","watermark","username","blurry","artist name","EasyNegative(V2)?(?!:)","(high|low|worst)[\\s_]*quality","lowers","(extra|fewer|missing)[\\s_]*(fingers|arms|legs)","logo","dated","sign","word","mosaic","censored"],slst=["Model:","Negative prompt:","Version:"],e=e=>e?.length?e.split(/[\n,] (?=[\w "]+: )/).join("\n").replace(/^\s*\n/mg,""):"no info",de=async d=>(await new Response((new Blob([d])).stream().pipeThrough(new DecompressionStream("deflate"))).arrayBuffer()),r=async a=>{let l1=(new TextDecoder("latin1").decode(ab=(await(await fetch(a.dataset.href)).arrayBuffer()))),u8=new Uint8Array(ab),t16=((idx=l1.search(/(?<=UNICODE\0)/u))!=-1)?(ed=l1.match(/(?:eXIf|Exif\0\0|EXIF[\s\S]{2}\0\0)(..)[\s\S]*?(?=UNICODE\0)/u),sz=u8[ed.index-2]*256+u8[ed.index-1],new TextDecoder("utf-16"+((ed?.[1]=="MM"||(u8[0]==0xFF&&u8[1]==0xD8))?"be":"")).decode(sz==0?ab.slice(idx):ab.slice(idx,idx+sz))):"",o=a.querySelector("div"),l=[...l1.matchAll(/(?<=(?:tE|iT)Xt(?:parameters|Description|Comment|prompt|metadata)\0+)([\s\S]+?)(?=[\s\S]{4}\0)/udg)]?.map(m=>(new TextDecoder("utf-8")).decode(ab.slice(m.indices[0][0],m.indices[0][1]))),z=await Promise.all([...l1.matchAll(/zTXt(?:parameters|Description|Comment|prompt|metadata)\0+/udg)]?.map(async (m)=>{h=m.indices[0][0],t=m.indices[0][1],cs=u8[h-4]*(2**(8*3))+u8[h-3]*(2**(8*2))+u8[h-2]*(2**8)+u8[h-1];return (new TextDecoder("utf-8")).decode(await de(ab.slice(t,h+4+cs)))})),d=t16.match(/[^%01]*/u)?.[0]?.replace(/[\uffdb\uffc0].*?$/,"");o.innerText=e((l?.join("\n")??"")+(z?.join("\n")??"")+(d?d:""));o.innerHTML=o.innerHTML.replace(slst.length?new RegExp("("+slst.join("|")+")","g"):/(?!)/,"<strong><u>$&</u></strong>").replace(dlst.length?new RegExp("[\\[\\{\\(]*(?<!\\w)("+dlst.join("|")+")(?!\\w):?-?[\\d\\.]*[\\]\\}\\)]*[,\\s]*","g"):/(?!)/,%27<span style="opacity:0.4">$&</span>%27)},a=e=>{let t=e.parentElement;if(t.dataset.done||!/\.(png|jpg|webp)$/.test(e.href))return;let a=document.createElement("details");a.innerHTML=%27<summary style="user-select:none;cursor:pointer;">Info</summary><div style="font-family:"chrome";max-width:50vw;overflow:auto;white-space:pre-wrap">...</div>%27,a.dataset.href=e.href,t.append(a),a.open=true,t.dataset.done=!0;r(a)},n=()=>[...document.querySelectorAll(".rtd a:last-of-type")].forEach(a);n();let o=new MutationObserver(e=>{e.forEach(e=>{if(!e.addedNodes.length)return;let t=e.addedNodes[0].querySelector(".rtd a:last-of-type");t&&n()})}),l=document.querySelector(".thre");l&&o.observe(l,{childList:!0})})();

56 無念 Name としあき 24/04/24(水)20:55:47 ID:wa0pRLg2 No.1209301399 そうだねx14
たておつ
ログを読んでたら「スレ閲覧時に便利なブックマークレット」最新版の
「デフォルトで開いてある版」が欲しいということだったのでやっつけ
https://xgf.nu/5aHXj

1000レス近くを完全に読み込むには少し時間がかかる
件数があまりに多すぎると画像読み込みのところでコケるかも…?

2024/3/15版

2024/3/15版
特徴

  • png内でマルチバイト文字が化けるのを修正
  • zTXt形式に対応
  • ステップ数やサンプラー等の生成パラメータ毎に改行するので見やすい
  • 「▶Info」のクリック時に情報を取得
  • ComfyUIから出力した画像にも対応
javascript:(()=>{let dlst=["masterpiece","best quality","score_\\d+(_up)?","lowres","bad (anatomy|hands)","text","error","missing fingers","(extra|fewer) digits?","cropped","(worst|low|normal) quality","jpeg artifacts","signature","watermark","username","blurry","artist name","(high|low|worst)[\\s_]*quality","lowers","(extra|fewer|missing)[\\s_]*(fingers|arms|legs)","logo","dated","sign","word","mosaic","censored"],slst=["Model:","Negative prompt:","Version:"],e=e=>e?.length?e.split(/[\n,] (?=[\w "]+: )/).join("\n").replace(/^\s*\n/mg,""):"no info",de=async d=>(await new Response((new Blob([d])).stream().pipeThrough(new DecompressionStream("deflate"))).arrayBuffer()),r=async a=>{if(!a.target.open)return;a.target.removeEventListener("toggle",r);let l1=(new TextDecoder("latin1").decode(ab=(await(await fetch(a.target.dataset.href)).arrayBuffer()))),u8=new Uint8Array(ab),t16=((idx=l1.search(/(?<=UNICODE\0)/u))!=-1)?(ed=l1.match(/(?:eXIf|Exif\0\0|EXIF[\s\S]{2}\0\0)(..)[\s\S]*?(?=UNICODE\0)/u),sz=u8[ed.index-2]*256+u8[ed.index-1],new TextDecoder("utf-16"+((ed?.[1]=="MM"||(u8[0]==0xFF&&u8[1]==0xD8))?"be":"")).decode(sz==0?ab.slice(idx):ab.slice(idx,idx+sz))):"",o=a.target.querySelector("div"),l=[...l1.matchAll(/(?<=(?:tE|iT)Xt(?:parameters|Description|Comment|prompt)\0+)([\s\S]+?)(?=[\s\S]{4}\0)/udg)]?.map(m=>(new TextDecoder("utf-8")).decode(ab.slice(m.indices[0][0],m.indices[0][1]))),z=await Promise.all([...l1.matchAll(/zTXt(?:parameters|Description|Comment|prompt)\0+/udg)]?.map(async (m)=>{h=m.indices[0][0],t=m.indices[0][1],cs=u8[h-4]*(2**(8*3))+u8[h-3]*(2**(8*2))+u8[h-2]*(2**8)+u8[h-1];return (new TextDecoder("utf-8")).decode(await de(ab.slice(t,h+4+cs)))})),d=t16.match(/[^%01]*/u)?.[0]?.replace(/[\uffdb\uffc0].*?$/,"");o.innerText=e((l?.join("\n")??"")+(z?.join("\n")??"")+(d?d:""));o.innerHTML=o.innerHTML.replace(slst.length?new RegExp("("+slst.join("|")+")","g"):/(?!)/,"<strong><u>$&</u></strong>").replace(dlst.length?new RegExp("[\\[\\{\\(]*(?<!\\w)("+dlst.join("|")+")(?!\\w):?-?[\\d\\.]*[\\]\\}\\)]*[,\\s]*","g"):/(?!)/,%27<span style="opacity:0.4">$&</span>%27)},a=e=>{let t=e.parentElement;if(t.dataset.done||!/\.(png|jpg|webp)$/.test(e.href))return;let a=document.createElement("details");a.innerHTML=%27<summary style="user-select:none;cursor:pointer;">Info</summary><div style="font-family:"chrome";max-width:50vw;overflow:auto;white-space:pre-wrap">...</div>%27,a.dataset.href=e.href,a.addEventListener("toggle",r),t.append(a),t.dataset.done=!0},n=()=>[...document.querySelectorAll(".rtd a:last-of-type")].forEach(a);n();let o=new MutationObserver(e=>{e.forEach(e=>{if(!e.addedNodes.length)return;let t=e.addedNodes[0].querySelector(".rtd a:last-of-type");t&&n()})}),l=document.querySelector(".thre");l&&o.observe(l,{childList:!0})})();

31 無念 Name としあき 24/03/15(金)23:43:52 ID:NuEFaSos No.1195801601 そうだねx19
'スレ閲覧時に便利なブックマークレット'をさらに改良
https://xgf.nu/GjiNy

png内でマルチバイト文字が化けるのを修正
zTXt形式に対応
これである程度の範囲のメタデータをカバーできてるはず…

表示を見やすく整形した版(2024/3/3)

表示を見やすく整形した版(2024/3/3)
特徴

  • ステップ数やサンプラー等の生成パラメータ毎に改行するので見やすい
  • 「▶Info」のクリック時に情報を取得
  • ComfyUIから出力した画像にも対応
javascript:(()=>{let e=e=>e?.length?e.split(/[\n,] (?=[\w "]+: )/).join("\n").replace(/^\s*\n/mg,""):"no info",r=async a=>{if(!a.target.open)return;a.target.removeEventListener("toggle",r);let t8=(new TextDecoder("latin1").decode(ab=(await(await fetch(a.target.dataset.href)).arrayBuffer()))),t16=((idx=t8.search(/(?<=UNICODE\0)/u))!=-1)?(ed=t8.match(/(?:eXIf|Exif\0\0|EXIF[\s\S]{2}\0\0)(..)[\s\S]*?(?=UNICODE\0)/u),u8=new Uint8Array(ab),sz=u8[ed.index-2]*256+u8[ed.index-1],new TextDecoder("utf-16"+(ed?.[1]=="MM"?"be":"")).decode(sz==0?ab.slice(idx):ab.slice(idx,idx+sz))):"",o=a.target.querySelector("div"),l=t8.match(/(?<=(?:tE|iT)Xt(?:parameters|Description|Comment|prompt)\0)([\s\S]+?)(?=[\s\S]{4}\0)/ug),d=t16.match(/[^%01]*/u)?.[0]?.replace(/\uffdb.*?$/, "");o.innerText=e((l?.join("")??"")+(d?d:""));o.innerHTML=o.innerHTML.replace(/(Model|Negative prompt):/g,"<strong><u>$&</u></strong>")},a=e=>{let t=e.parentElement;if(t.dataset.done||!/\.(png|jpg|webp)$/.test(e.href))return;let a=document.createElement("details");a.innerHTML=%27<summary style="user-select:none;cursor:pointer;">Info</summary><div style="font-family:"chrome";max-width:50vw;overflow:auto;white-space:pre-wrap">...</div>%27,a.dataset.href=e.href,a.addEventListener("toggle",r),t.append(a),t.dataset.done=!0},n=()=>[...document.querySelectorAll(".rtd a:last-of-type")].forEach(a);n();let o=new MutationObserver(e=>{e.forEach(e=>{if(!e.addedNodes.length)return;let t=e.addedNodes[0].querySelector(".rtd a:last-of-type");t&&n()})}),l=document.querySelector(".thre");l&&o.observe(l,{childList:!0})})();

90 無念 Name としあき 24/03/03(日)15:13:25 ID:IXl2n5Vo No.1191807017 そうだねx15

1709446405598.jpg

'スレ閲覧時に便利なブックマークレット'を改造したので
https://xgf.nu/nYPEE

項目ごとに改行を追加(縦に長くなるけど…)
区切りになるNegative prompt:と注目するModel:を強調表示
日本語にもある程度対応
一部の形式で末尾にゴミが付いたり一部NAIにあったzTXt形式には非対応です

デフォルトで閉じてある版(以下、2023/03/17)

デフォルトで閉じてある版

javascript:(()=>{
  let exif=(str)=>{let res = "";for(let i=0;i<str.length;i=i+2){res=res+str[i]}return res;};
  const exifinfo = ()=> [...document.querySelectorAll('a[href$=".jpg"]:last-of-type, a[href$=".webp"]:last-of-type')].forEach(async e=>{
    if(!e.dataset.fetched){
      e.dataset.fetched=true;
      const m=(await(await fetch(e.href)).text()).match(/UNICODE*([^]*)/u);
      m&&(e.parentElement.innerHTML+=`<details><summary>Info</summary><pre style="white-space:pre-wrap">${exif(m[1]).replace(/&/g,'&amp;').replace(/</g, '&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;')}</pre></details>`)
    }
  });
  const pnginfo = ()=> [...document.querySelectorAll('a[href$=".png"]:last-of-type')].forEach(async e=>{
    if(!e.dataset.fetched){
      e.dataset.fetched=true;
      const m=(await(await fetch(e.href)).text()).match(/(?<=Xt(?:parameters|Description|Comment)\0*)([^\0]+)/ug);
      m&&(e.parentElement.innerHTML+=`<details><summary>Info</summary><pre style="white-space:pre-wrap">${m.join('').replace(/&/g,'&amp;').replace(/</g, '&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;')}</pre></details>`)
    }
  });
  exifinfo();
  pnginfo();
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (!mutation.addedNodes.length) return;
      const rtd = mutation.addedNodes[0].querySelector(".rtd");
      if (rtd) {
        exifinfo();
        pnginfo();
      }
    });
  });
  const target = document.querySelector(".thre");
  if (target) observer.observe(target, {childList: true});
})();
デフォルトで開いてある版

デフォルトで開いてある版

javascript:(()=>{
  let exif=(str)=>{let res = "";for(let i=0;i<str.length;i=i+2){res=res+str[i]}return res;};
  const exifinfo = ()=> [...document.querySelectorAll('a[href$=".jpg"]:last-of-type, a[href$=".webp"]:last-of-type')].forEach(async e=>{
    if(!e.dataset.fetched){
      e.dataset.fetched=true;
      const m=(await(await fetch(e.href)).text()).match(/UNICODE*([^]*)/u);
      m&&(e.parentElement.innerHTML+=`<details open><summary>Info</summary><pre style="white-space:pre-wrap">${exif(m[1]).replace(/&/g,'&amp;').replace(/</g, '&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;')}</pre></details>`)
    }
  });
  const pnginfo = ()=> [...document.querySelectorAll('a[href$=".png"]:last-of-type')].forEach(async e=>{
    if(!e.dataset.fetched){
      e.dataset.fetched=true;
      const m=(await(await fetch(e.href)).text()).match(/(?<=Xt(?:parameters|Description|Comment)\0*)([^\0]+)/ug);
      m&&(e.parentElement.innerHTML+=`<details open><summary>Info</summary><pre style="white-space:pre-wrap">${m.join('').replace(/&/g,'&amp;').replace(/</g, '&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;')}</pre></details>`)
    }
  });
  exifinfo();
  pnginfo();
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (!mutation.addedNodes.length) return;
      const rtd = mutation.addedNodes[0].querySelector(".rtd");
      if (rtd) {
        exifinfo();
        pnginfo();
      }
    });
  });
  const target = document.querySelector(".thre");
  if (target) observer.observe(target, {childList: true});
})();
レスいっぱいあると重いので▼Info開いたときに取得する版

レスいっぱいあると重いので▼Info開いたときに取得する版
勝手に改造しましたすみません
edgeのスニペットで動作確認してるのでブックマークレットで動かなかったら教えて

javascript:(()=>{
const parse = (str) => !str?.length ? 'no info' : str.split(/[\n,] (?=[\w ]+: )/).join('\n')
const exif = (str) => !str?.length ? '' : (new TextDecoder('utf-16')).decode(Uint8Array.from(str.split('').map(x => x.charCodeAt())))
const getInfo = async e => {
  if (!e.target.open) return
  e.target.removeEventListener('toggle', getInfo)
  const t=(await(await fetch(e.target.dataset.href)).text())
  const pre=e.target.querySelector('div')
  const png=t.match(/(?<=Xt(?:parameters|Description|Comment)\0*)([^\0]+)/ug)
  const webp=t.match(/UNICODE*([^]*)/u)
  pre.textContent = parse((png?.join('') ?? '') + (webp ? exif(webp[1]) : ''))
}
const addDetails = x => {
  const td = x.parentElement
  if (td.dataset.done || !/\.(png|jpg|webp)$/.test(x.href)) return
  const d = document.createElement('details')
  d.innerHTML = `<summary style="user-select:none;cursor:pointer;">Info</summary><div style="font-family:'chrome';max-width:50vw;overflow:auto;white-space:pre-wrap">...</div>`
  d.dataset.href = x.href
  d.addEventListener('toggle', getInfo)
  td.append(d)
  td.dataset.done = true
}
const refresh = () => [...document.querySelectorAll('.rtd a:last-of-type')].forEach(addDetails)
refresh()
const observer = new MutationObserver((mutations) => {
  mutations.forEach((mutation) => {
    if (!mutation.addedNodes.length) return;
    const rtd = mutation.addedNodes[0].querySelector('.rtd a:last-of-type')
    if (rtd) refresh()
  })
})
const target = document.querySelector(".thre")
if (target) observer.observe(target, {childList: true})
})()
レスいっぱいあると重いので▼Info開いたときに取得する版(圧縮版)

レスいっぱいあると重いので▼Info開いたときに取得する版(圧縮版)
ブックマークレットが1行じゃないといけないとか色々でオリジナル版が動作しないことがあったので1行に収めたバージョン
Google Chromeで動作確認済みです

javascript:(()=>{let e=e=>e?.length?e.split(/[\n,] (?=[\w ]+: )/).join("\n"):"no info",t=e=>e?.length?new TextDecoder("utf-16").decode(Uint8Array.from(e.split("").map(e=>e.charCodeAt()))):"",r=async a=>{if(!a.target.open)return;a.target.removeEventListener("toggle",r);let n=await (await fetch(a.target.dataset.href)).text(),o=a.target.querySelector("div"),l=n.match(/(?<=Xt(?:parameters|Description|Comment)\0*)([^\0]+)/ug),d=n.match(/UNICODE*([^%01]*)/u);o.textContent=e((l?.join("")??"")+(d?t(d[1]):""))},a=e=>{let t=e.parentElement;if(t.dataset.done||!/\.(png|jpg|webp)$/.test(e.href))return;let a=document.createElement("details");a.innerHTML=%27<summary style="user-select:none;cursor:pointer;">Info</summary><div style="font-family:"chrome";max-width:50vw;overflow:auto;white-space:pre-wrap">...</div>%27,a.dataset.href=e.href,a.addEventListener("toggle",r),t.append(a),t.dataset.done=!0},n=()=>[...document.querySelectorAll(".rtd a:last-of-type")].forEach(a);n();let o=new MutationObserver(e=>{e.forEach(e=>{if(!e.addedNodes.length)return;let t=e.addedNodes[0].querySelector(".rtd a:last-of-type");t&&n()})}),l=document.querySelector(".thre");l&&o.observe(l,{childList:!0})})();

これで準備はOKです。あとは「スレを開いた状態」でこのブクマを使用してみてください。
スレ全体に対して効果を発揮し、個々のレス部分に「▼Info」と表示が出て画像のメタデータ(プロンプト等)が見れるようになります。
「▼Info」部分をクリックすることで開閉できます。
後から読み込まれたレスに対しても自動で適用されるので、ブクマを再実行する必要はありません。
対応形式:png、jpg、webp
ただしNMKDで生成した画像のメタデータには未対応となります。初心者向けや1111のPNG Infoタブを利用してください。
また、モザイク処理やファイル形式の変換等によりメタデータが消失している画像の分は、もちろん表示できません。悪しからず。

※android端末でのスレ閲覧時には、URLバーを押しブックマークレットの名前を入れ選択することで使用できます。

出典
96無念Nameとしあき23/03/17(金)20:52:31 ID:/3JHyZBo[2]No.1077255473No.1077255473 ngそうだねx22
たておつkemono
ブックマークレット更新しました
あとから読み込まれたレスにも自動で反応するようにしました
もう何度もポチポチしなくても大丈夫
fu2017743.txt

NovelAIの強調をwebuiの強調に変換

NovelAIのプロンプト(呪文)をwebui等に流用したい時に役立つブクマ。

javascript:(()=>{let a=0,b='',d=0,m=0,l=0;for(const c of window.prompt('変換したいNAIのプロンプトを入力してください')){if(c=='{'){a++,m=a;if(a==1){b+='('}}else if(c=='}'){a--;if(a==0){b+=':'+(Math.round(10000*1.05**m)/10000)+')',m=0}}else if(c=='['){d++,l=d;if(d==1){b+='('}}else if(c==']'){d--;if(d==0){b+=':'+(Math.round(10000*(1/1.05)**l)/10000)+')',l=0}}else{b+=c}};window.prompt('変換しました。コピーしてください',b)})()
出典
やっつけだけどNAIの強調をwebuiの強調に変換するブックマークレット作った
入力ダイアログが出るからそこにNAIのプロンプトをコピペしてOK→変換後のプロンプトがまたダイアログで出るのでコピーする
javascript:(()=>{let a=0,b='',d=0,m=0,l=0;for(const c of window.prompt('変換したいNAIのプロンプトを入力してください')){if(c=='{'){a++,m=a;if(a==1){b+='('}}else if(c=='}'){a--;if(a==0){b+=':'+(Math.round(10000*1.05**m)/10000)+')',m=0}}else if(c=='['){d++,l=d;if(d==1){b+='('}}else if(c==']'){d--;if(d==0){b+=':'+(Math.round(10000*(1/1.05)**l)/10000)+')',l=0}}else{b+=c}};window.prompt('変換しました。コピーしてください',b)})()

埋め立て連投荒らし削除(2023/03/12版)

荒らし出現中に使用すると荒らしのレスは一掃されますが、副作用として荒らしではない普通の文字レスも一緒に削除されます
導入・エラーその他何かしらの質問がある時は何かしらの画像も一緒に貼り付けて質問しましょう。
なお、FTBucketの過去ログ(過去2日分)に対しても利用できます。

長いので折り畳み
javascript: (() => {
  const hide = (node) => {
    node.closest("table").style.display = "none";
  };
  const checkimg = (ele) => {
    const img = ele.querySelector("img");
    if (img) {
      const alt = img.getAttribute("alt");
      if (!alt.match(/\d{4}/)) {
        hide(ele);
      }
    } else {
      hide(ele);
    }
  };
  const res = document.querySelectorAll(".rtd");
  if (!res) return;
  res.forEach((ele) => {
    checkimg(ele);
  });
  const target = document.querySelector(".thre");
  if (!target) return;
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      if (!mutation.addedNodes.length) return;
      const node = mutation.addedNodes[0];
      const rtd = node.querySelector(".rtd");
      if (rtd && !node.querySelector(".rtd img")) {
        hide(node);
      } else if (rtd) {
        checkimg(rtd);
      }
    });
  });
  observer.observe(target, {
    childList: true,
  });
})();
出典
49無念Nameとしあき23/03/12(日)17:38:42 ID:b/ltdKSgNo.1075554753No.1075554753 ngそうだねx4
たておつkemono
汚物は消毒だ~ブックマークレット置いとくね
fu2002092.txt
動作は変わってないけどちょっとだけきれいに書き直しといた

ふたクロ用NGワード

FutaKuro(ふたクロ)はブラウザ用拡張機能(1111用拡張機能ではない)。
GoogleChromeやChromium派生ブラウザで利用可能。
ふたばちゃんねるでの閲覧がより快適になる。
https://futakuro.com/

スクリプト荒らし対策のNGワード設定方法

  1. ふたクロを導入後、AI絵スレを開いた状態で「NG設定」を開く
  2. ヘッダ欄に
    ^(?!.*_blank).*$
    をコピペして「正規表現」をON
  3. 「追加」ボタンを押す
  4. ヘッダ欄に
    ¥(¥d{1,4} B¥)
    をコピペして「正規表現」をON
  5. 「追加」ボタンを押す

始める前に

Windowsのユーザー名は半角英数字にしよう!
(一般的に2バイト文字は避けるのが無難)


短縮URL生成

https://wikiwiki.jp/sd_toshiaki/-s/0dd28e00