AIイラスト体験

twitterでおすすめとかでTLに流れてくるツイートの中に、AIグラビアの画像がたまたま流れてきて「グラボを買えばできるよん」みたいな感じだったので、やり方を調べてやってみた。

#ChillOutMix

まずはdGPU、GeForceのグラボがいるみたい。ググるとGeForce RTX-3060 12GBのものを買えばいいみたい。
買う前に今のパソコンで使えるかどうか。。。今のPC環境は、ストレージを除けば5年以上の前のもの。

  • CPUはCore i7 8700 (無印)
  • メモリは32GB (8GB x 4)
  • 電源は10年前に買った玄人志向の550W 80PLUS GOLD
  • M/BはASUSのPrime Z370-A

という構成。一応 PCIe rev3なので、PCIe rev4のRTX-3060はギリ、搭載できる。
メーカーによって推奨電源が650Wだったり、550Wだったりと若干不安は残るが、認識しなければ電源も買い替えればいいし・・・ということでちょうど在庫があったGIGABYTEの GV-N3060EAGLE OC-12GD R2.0を買って、取付け、UEFIで認識しているのを確認してWindows起動成功。

NVIDIAサイトからドライバをダウンロードしてインストールしたらちゃんと使えるようになった!
一応5〜6時間ぶっとおしで動画エンコードしながらPC使って見ても落ちないので電源は 550W でも十分使えそう。
ちなみに、GPUが100%で振り切っている状態で、UPSの状態を確認したら負荷電力がMAXで280〜360Wぐらい。CPUが K型番じゃなく無印の省電力版Core i7なので、まだちょっと余裕があるみたいな感じ。

次に、AIイラストの環境構築。システム自体は、Python3 で動く Stable Diffusion と Web UIで動かすみたいで、これもググると、githubからcloneするだけらしい。

PythonとGit は、コマンドプロンプトから winget でインストールすれば一瞬でインストールできる。

> winget install -h Python.Python.3.10
> winget install -h Git.Git

コマンドプロンプトを一度閉じ、もういちど コマンドプロンプトを出してから作業。正しくインストールされていれば、pythonとgitにPATHが通っているはずなので、gitもしくはpythonを叩いて確認する。

あとは適当なフォルダ(ディレクトリ)を作って、そのディレクトリで git cloneして、webui.bat をコールすれば、初回起動は時間はかかるが2回目からすぐに起動できる。

> git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
> cd .\stable-diffusion-webui
> .\webui

さて、あとは、ChilloutMix とかいうモデルファイルを入れたり、LoRAというものを探して入れたり、ググるといっぱいやり方がでてくるので割愛するけど、旬な話題みたいで、いっぱいブログ記事がヒットするんだけど、詳しくないので、どれが正しい情報なのか、イマイチ分からない。
しかも使われている用語がわけわからんので、一つ一つ調べて前に進めるしかない、と諦めてる。

試行錯誤しながら、画像を生成してみた。

#ChillOutMix

なんか手が6本になったり、股から足がニョキニョキ生えた画像が出てきたり、やたらヌード画像になったり、まだ呪文(プロンプト)の入力が分からん。。。。

しばらく遊んでみます。。。

ブラウザでPDFファイルの画像化

持病の影響で急性腎不全を患い、少しばかり入院していました。はぁ~、健康って大事ですよねぇ。。。
というのは、さておき。

コーディング・メモです。

PDFファイルの画像を生成するため、アップロードしたPDFファイルをサーバーで(具体的には ImageMagickで)処理していました。
周知のとおり、ImageMagickでPDFファイルを処理するとセキュリティー云々があってごく限られた場合に使用するようにしていました。
ImageMagickはいいですね、もう画像関連の処理は全部コイツに任せたいぐらいですが、4~5年前に脆弱性に関する情報がいっぱい出て使うのをためらっています。2022年末になってもまだ同じ状況なのでしょうか?よく分かりません。

というわけ・・・でもないのですが、サーバーサイドでImageMagickに頼らず、ということになるとImageMagickの代替を探すか、自作するしかありませんが、画像のアルゴリズム他に関する知見はほとんどないので自前でなんとか、というのはできない。となると、クライアントでどうにかするしかありません。

幸いにも、最近のウェブ環境ではJavaScriptでどうとでもなります。
PDFフォーマットの解析・表示には、MozillaさんがPDF.js を公開してくれてます。今更ですが。

A general-purpose, web standards-based platform for parsing and rendering PDFs.
PDF.js

これを使うと、File,Blobなどで取得したPDFデータを HTMLに書いたcanvas要素にレンダリングしてくれます。
canvas要素にレンダリングしてくれたら、あとは canvas要素の画像を取得して Blob に変換してあげて、サーバーにPDFとともに生成した画像を送信してやれば、サーバー側で重い処理を走らせずに済みます。

上記サイトにサンプルがあるので、チョチョっといじれば、簡単に実装できる、いい時代です。
最初、ダウンロードしたファイルのどれが必要なのかよく分かんなかったですが・・・、最終的に、以下のように buildディレクトリとcmapsディレクトリさえあれば、事足りるみたい。

.
└── pdfjs
    ├── build
    │   ├── pdf.min.js
    │   ├── pdf.sandbox.min.js
    │   ├── pdf.worker.entry.js
    │   └── pdf.worker.min.js
    └── cmaps/*

とりあえず動作デモ
ソースを見れば大体何をやってるかは分かると思います。チョーカンタン。

input[type=file]要素でファイルを読み込んで、それをそのまま渡すと変換した画像のFileオブジェクトを返してくれるような関数を書いてみました。再利用しやすいようにとりあえずモジュールとして書いた。

これを、下記のようにコール。

ものすごく、簡単。

上記のデモはこっち。

ブラウザでCSV(CP932)⇔XLSXの相互変換

極力サーバーサイドでExcelファイルを処理させたくなくて、(なんちゃって)フロントエンド開発をワチャワチャやっております。

データベースからデータを抜き出すのも、Excelファイルだし、データベースにインポートするデータもExcelファイルです。 もうエクセルを見るのも嫌になってます。

サーバーサイドのプログラムを組む時、データをJSONもしくはCSV形式で扱うと、書くのがラクになります。そこで、ブラウザ上で、CSVとXLSXを相互変換できれば便利だな、と思ったのがきっかけ。

例によって、node.jsモジュールを browserify でワンパッケージにして利用します。(バンドラーって呼ぶみたいです。よく分からん)今回は npmコマンドで exceljs・encoding.js・file-saver の三つのモジュールを取得して、browserify で一つのファイルにパックします。

exceljs は、Excel(xlsx)ファイルを扱うモジュール。ExcelファイルをJavaScriptで扱うライブラリは SheetJS が有名で xlsxだけじゃなくて旧型式のxlsファイルも読むことができて非常に便利なのですが、Pro版じゃないと制限が多いので、最近では ExcelJSの方を使っています。

encoding.js は JavaScript でUTF-8,ShiftJIS(CP932),UTF16などを相互に変換できるライブラリです。ShiftJISのCSVファイルを扱う時に使用します。

file-saverは・・・説明要らないですよね💦 ダウンロードできるようにするヤツです。


動作デモはこちら


手順はいつもどおり。
まずは、package.json 。

今回は 3つのモジュールを一つのファイル(bundle.min.js)にまとめて、実際に使用するときは、そのファイル内(bundle.min.js)に定義されているrequire関数でロードするようにします。

上記package.jsonを適当なディレクトリにおいて下記を実行して、bundle.min.js を生成しておきます。

>> npm install
>> npm run bundle

この bundle.min.js を下記のサンプルのHTMLファイルのように、scriptタグでロードしておきます。

そして・・・肝心の 変換コードは下記のようになります。

特筆すべき点はありませんが・・・encoding-japaneseモジュールで、ShiftJISに変換した後、ShiftJISに変換したものを保存するとき、単純 string型でBlobのコンストラクタに渡すと、再変換されて文字化けを起こしてしまいハマってしまいました。
イマイチあんまり分かってません。

CSVの行区切り、本来は・・・CRLF(0x0D0A)・・・ですよね・・・。workbookからCSVにするとき、worksheetを行毎にループして変換したあと、自前で join(‘\r\n’)とかすればいいんでしょうけど・・・。
workbook.csv.writeBuffer()する際、formatterOptionでrowDelimiterで改行コードを指定すればいいみたい。

フロントエンド、メンドクサイし、ムズカシイし、あんまりやりたくない。。。


動作デモはこちら


簡易ISOファイル作成コマンド

■2021年8月2日 追記


これの続きです。

自分用のツールの置き場、備忘録として記録しています😅

CDやDVDのメディアからISOファイルを作成するのは結構カンタンにできました。
これで殆どやりたいことはできたのですが、やっぱりディレクトリからISOファイルを作るにはどうするんだろう??? という素朴な考えがでてきまして・・・

————– 追記
これが 非Windows OSならば、mkisofs コマンド(genisoimage)をdnfなりaptなりのパッケージマネージャで入れれば解決するんだけど・・・いかんせん、Windowsはそういう便利なコマンドはありません。oscdimg という Windowsのインストールメディアを作成するツールを使えばできるそうです。実用性を重視する人は oscdimg を使うといいと思います😀
追記ここまで —–

ググるとこれもWindowsで標準機能でできるようで・・・具体的にはイメージマスタリングAPIとしてCD/DVD等のファイルシステム作成からメディアへの書き込みまでの機能がCOMサーバーとして提供されているようです。COMサーバーで実装ってことは、WSHやC#から簡単に使える・・・ってことです。

サンプルのコードはもうマイクロソフトのコミュニティーサイトに載ってましたので、これを適当にいじって、任意のディレクトリをISOファイルにビルドできるコードを書いてみました。一つ前に書いたDVDメディアからISOファイルを作るコードも統合してみました。

イメージマスタリングAPIは.NET Frameworkのクラスライブラリで提供されておらず、C#から使用するには、TLBIMPコマンドを使用してタイプライブラリからCLRアセンブリに変換し、コンパイルするときにこのアセンブリを参照しないといけません。Visual Studio のIDE環境を使用する場合はプロジェクトにIMAPI2FS.dllの参照を追加するだけでいいかもしれません。
僕みたいにコンソール画面でカチャカチャする場合は・・・

>> tlbimp c:\WINDOWS\System32\imapi2fs.dll

のようにすると、同名のアセンブリ(dllファイル)ができるので、ソースコードをコンパイルするときに、このDLLファイルを /r オプションで追加します。

殆どサンプルコードをコピペしただけなので、特に特筆するところはありません・・・githubにリポジトリ作ろうと思ったけど、ファイル1個だけなんでgistにした。

一応、タイプライブラリのインポートもあるので nmake用の makefileも書く。

DVDメディアのダンプ

Windows7の環境が必要になり開発用のプロダクトキー?を発行してもらい、後はHyperV環境で仮想マシンを作ってインストールするだけ。
って思ってたら、罠が・・・HyperVで稼働しているマシンにDVDを読めるドライブがねぇよ。。。
DVDメディアからISOファイルを作れば・・・と思い、Windows10のアクセサリの中にISOファイルを作るアプリを一応探してみたけど当然なく・・・、WindowsってISOファイルからメディアに焼く機能はエクスプローラから呼び出せるのに、その反対ができない・・・。

むむむ、linuxとかだと、ddコマンドで一発なのに・・・WSLからddでDVDドライブのデバイスを指定して・・・ってできないのかなぁ・・・。

仕方ないので窓の杜でフリーソフトを漁るか・・・とも思いましたが・・・、単にドライブをオープンしてダンプすればエエだけやろ? ってことで、C#で書いた。C#からWindows APIをコールするところはマイクロソフトのサイトからコピペして、適当に。

要点は、Windows APIの CreateFile から返る SafeFileHandleをFileStreamに渡してバッファを介してコピーするだけ。
FileStream.CopyToAsyncメソッドを使えば一行で済むんだけど、やっぱり途中経過(進捗状況)は必要かなー、と思って無理やり FileStream.ReadAsync/WriteAsyncメソッドを使ったけど・・・。