まだプログラマーですが何か?

プログラマーネタ中心。たまに作成したウェブサービス関連の話も https://twitter.com/dotnsf

タグ:mydoodles

某所で話題になっていた記事を読んで、自分にも興味ある内容だったので参戦してみました:

絶対に画像をダウンロード&スクレイピングさせないWebページを本気で作ってみた


内容は上記サイトのタイトル通りです。自分はマンホールマップお絵描き日記といった画像投稿機能を持つサービスを開発・運営しています。そんな中でサービスに参加していただいたユーザーが投稿した作品を「勝手にダウンロードして別のところで使われる」ことはサービス運営の観点で好ましくない自体ではあります。一方で「ウェブで閲覧できる画像のダウンロードを技術的に禁止する」のは結構難しいテーマで、これまで真剣に取り組んでいませんでした(ブロックチェーンを使ったり、作品の NFT 化といった対処は既に実装しているのですが、これらはいずれも「オリジナル作品のダウンロードそのものを禁止する」という技術ではありません)。で、上記サイトを見て、改めて自分でも本気でこのテーマに取り組んでみようと思ったわけです。


【画像のダウンロード禁止がなぜ難しいか?】
ここからは少しウェブの知識を必要とする内容になります。まずは「そもそも何故ウェブ画像のダウンロード禁止が難しいか?」を説明します。

普通のウェブページで普通に画像を表示しようとすると、<img> という HTML タグを使って表示します。例えばこんな感じです:
<img src="https://avatars.githubusercontent.com/u/3183150?v=4" />


<img> というタグが画像を表示する機能を持ち、その "src" という属性で画像の URL(場所)を指定します。この例であれば "https://avatars.githubusercontent.com/u/3183150?v=4" が画像の URL になっています。この URL をウェブブラウザで直接指定すると画像だけが表示されます(他にも <img> の属性があり、指定内容によって見え方を変えることができますが、ここでは省略します)。このような「普通の」画像は画像上を右クリックしてから「画像を保存」することで簡単にダウンロードできてしまいます:

2023060403


このように「ウェブで画像を表示するには <img> タグを使う」のですが、「<img> の src 属性に画像の URL が指定されている」ため、ウェブページの HTML を見ることでどこに画像があるかが分かってしまうのです。ウェブページそのものをうまく作ることで右クリックを禁止する(右クリックのメニューからの「画像を保存」をできなくする)ことはできても、画像の URL がわかってしまうと、その URL を直接指定して開くことで「うまく作ったつもりの」ウェブページの仕組みを回避して保存できてしまうことになります。ウェブページの HTML を開けなくすることはできないため、「HTML を見られても画像の URL やデータがバレないようにする」必要がありました。

ややこしいことに「スクリーンショットで画像を保存する」ことへの対策も必要です。Windows や macOS のスクリーンショットで画像が表示されている状態のウェブページを丸ごとコピーして、画像アプリなどにペーストし、必要であれば画像部分を切り抜いて保存する方法です。この方法を使うと厳密な意味では画像の解像度なども変わってしまうのですが、そこまで気にしなければ(少なくともウェブや PC の画面で見る上では)ほぼ同じ画像を手に入れることができてしまいます。これは最早ウェブだけでどうにかできる話ではなく、OS レベルで対策が必要になるため、技術的にも非常に面倒な対策が必要になるものです。

そしてもっと面倒なこともあります。「開発者ツール」とか「Developer Tool」と呼ばれるウェブページ開発時に使われる確認ツール(ウェブブラウザの機能)があるのですが、これを使うと HTML 上ではわかりにくい画像(JavaScript を使ってプログラミングで動的に作成する画像)なども検知できてしまいます。ここまで含めて対策するのはかなり厄介といえます(なので私も対策の優先度を下げていました)。

以上のようにウェブで画像のコピーやダウンロードを禁止しようとすると、以下3つの対策が必要になります:
  1. HTML 内に画像の URL を残さない
  2. スクリーンショットへの対策
  3. 開発者ツールへの対策

【上記サイトでの対策方針】
先述した上記サイトではこれら3つの対策が全て実装されていました。内容を読んだ私の理解が正しければ以下のような方針が取られていました:

1. および 3. への対策

  • <img> タグを使わず、JavaScript を使って <canvas> タグ内に画像を描画して表示する
  • サーバー側で画像データを暗号化し、ブラウザ側で復号化し、データ URL("data:image/png;base64,xxxxxx...")形式で画像データを扱う
  • JavaScript は難読化する
  • (ここまでやればあまり意味はなく、ページ内でも「おまけ」と表現されていますが)ページ内で右クリックを無効化する JavaScript を実装する


2. への対策

  • オリジナル画像を表示せず、コピーライト文章を画像に上書きして表示する(上述の <canvas> 内にテキストを上書きして表示する)


まず目からウロコだったのは 2. への対策でした。表示される画像がオリジナルのものではないので(画像の右下にコピーライト文章が上書きされた画像なので)スクリーンショットを撮っても元画像は保存できない、という考え方でした。なるほど、その手があったか、、という印象でした。

加えて、<img> を使わずに(HTML5 の)<canvas> を使って画像を表示すること & 暗号化された画像データを受け取って復号化すること によって、HTML 内の情報から画像データを推測したり取り出したりすることを困難にする、ということも行っているようです。データ URL のテキストすら残さないやり方なので、かなり徹底した対策になっていると感じました。

一方で、同ページ内にも書かれていましたが、これでもまだ 100% の対策とは言えない要素もあります。JavaScript は難読化されているとはいえ解読不可能というわけではないため、暗号化したデータを復号化するコードを特定されてしまうと、同じロジックでデータを復号化して画像データを取り出し、その画像を保存する、ということは不可能ではないのでした。

また、これは私自身の印象なのですが、1枚の画像を守るためのページでこれだけの処理をするのはまだいいとして、画像が一覧で表示されるようなページで、全ての画像にこれだけの処理を実行して守った場合に、ページそのものの処理がかなり重くなってしまうのではないか?という懸念を感じました。例えば1ページ内に 100 枚の画像があったら、これだけの処理をブラウザ内で 100 回行う必要があるわけです。検索の仕組みなどがあると、検索結果となる画像全てにこの処理を行う必要もでてきます。今自分が開発・運営しているサービスの中でこの方法をそのまま実装するのは・・・ と感じています。


【自分で考えた対策方針】
では、実際に自分のサービスに実装する前提で、自分だったらどうやって画像のダウンロードを禁止するかを考えてみました。

ヒントとなったのは上述の 2. への対策(スクリーンショット対策)として書かれている方法でした。これはダウンロードそのものを禁止するとか、HTML からオリジナル画像にアクセスするための痕跡を消すとかいう考え方ではなく「そもそもオリジナル画像ではなく、コピーライト文章を上書きした画像を表示することで、オリジナル画像の保存を不可能にする」という方法および実装でした。これを自分のサービスの特性に合わせて応用する方法を思いつきました。

たまたま自分が実装を考えていたウェブアプリは「(IDとパスワードによるログインで)ユーザーの認証」を行うタイプのものでした。ログインしなくてもアプリを参照することはできますが、画像投稿はログイン後でないとできないタイプのものです。この場合は以下のような方法でもオリジナル画像のダウンロードを禁止することができるのではないかと考えました:

1. 画像の参照はオブジェクトストレージなどに格納して URL で参照するのではなく、画像の ID をパラメータに受け取って画像(バイナリ)情報を返す REST API の形で実現する。
2. ユーザーのログインをサーバー側でセッションとして管理する(セッション管理は必須ではないが、1. の REST API リクエストがどのユーザーからのものかを識別できるような仕組みを用意する)
3. 1. の REST API をリクエストしてきたユーザーが画像の持ち主と一致した場合は画像データをそのまま返す。リクエストユーザーが画像の持ち主とは別ユーザーだったり、そもそもログインしていないユーザーからのリクエストだった場合は画像データに加工(画像の一部にコピーライトメッセージを上書き)してから返す。

例えば画像 ID が xxxx である画像を表示するための REST API を "https://servername/attachment/xxxx" のように用意します。この URL にログイン済みのユーザーから、かつその画像の持ち主ユーザーからリクエストがあった場合のみ投稿された画像をそのまま返し、それ以外の場合は画像を加工してから返す、とすればいいのではないかと考えました。特定の画像を表示するための URL は(ログイン有無やユーザーの違いに関係なく)常に一意でいて、しかし返される画像のバイナリ情報はユーザーによって異なり、オリジナルの画像が返されるのは投稿ユーザーからのリクエストだった場合だけ、というものです。この方法だと同じ URL でも返される内容が異なるのでキャッシュは使えなくなりますが、既存のウェブアプリからの変更箇所は(REST API のパス部分に変更がないので、画像を返す REST API の中だけを変更し、セッション内のユーザーと画像の投稿者が同一であることを確認し、異なっていた場合のみコピーライトメッセージを上書きする処理を追加するだけで済むので)UI 側にほとんど変更がなく、比較的影響範囲が小さくなると思いました。

更にこの方法では、

- 画像を表示する方法はあくまで1つなので(パラメータも同じ REST API なので)、画像 URL を隠さなくても投稿者本人がログインした上でのリクエストでない限りはオリジナル画像を取り出すことができない(複雑な仕組みで画像 URL を隠す必要がない)

- 複数の画像が表示される一覧ページでも、1枚の画像が表示される詳細ページでも HTML や JavaScript に特別な違いを意識することなく同様に表示することができる

という副産物のメリットもあります。

加えて、これは私のウェブアプリでは 1 と 2 の部分はほぼ実装済みであったため、実質 3 の変更だけをすれば済む形になりました。自分の設計的にもこの方法が効率的だったという理由もあります。


【実装してみた】
実際に自分が運用しているお絵描き日記サービスでこの機能を有効にしてみました。興味ある方は実際に参照してみて(よかったら ID も作成してみて)ください。

まずログイン前にトップページを表示するとこのように表示されます(右上のボタンが黄色の場合はログイン前です)。表示される全てのお絵描き画像は画像を取り出す REST API 経由で取得しており、今回はログインしていないユーザーからのリクエストなので、全てのお絵描き画像にコピーライトメッセージ(図の青枠部分、実際の画像には青枠はありません)が付与されています。お絵描きの一覧ページでも、後述の個別ページでも同様です:
2023060400


ちなみにこのコピーライトメッセージ部分を拡大するとこのように表示されます。赤字で "© (投稿者の ID)@MyDoodles" と表示されています。"MyDoodles" はアプリ名です。オリジナルのお絵描き画像にはこのコピーライトメッセージはなく、API がこのメッセージをお絵描き画像の右下に上書きした上で結果を返しています:
2023060401


画面を下にスクロールすると色んな利用者から過去に投稿されたお絵描き画像が表示されていきます。この時点ではサービスにログインしていないので、全てのお絵描き画像にコピーライトメッセージが上書きされて表示されています:
2023060401


特定の1つのお絵描き画像を選択すると、そのお絵描き画像画像の詳細画面に移動します。このお絵描き画像は本当は私自身が投稿したものですが、まだログインしていないので(投稿者本人かどうか確認できないので)ここにもコピーライトメッセージが表示されています:
2023060402


別の利用者が投稿したお絵描き画像を詳細画面で表示した場合も、同様にコピーライトメッセージが上書きされた画像として表示されます:
2023060403



次にログイン後に同じページを参照してみます。画面右上の黄色いログインボタンをクリックしてログイン(またはサインアップしてからログイン)します:
2023060400


ログインに成功すると画面右上のボタンは緑になり、自分のアイコン画像に切り替わります。ログイン後の一覧画面では自分が投稿したお絵描き画像は(コピーライトメッセージが付与されず)オリジナル画像の状態で表示され、自分以外の利用者が投稿したお絵描き画像にはコピーライトメッセージが残る形で表示されます:
2023060401


下にスクロールして先ほどと同じ部分を見ています。上のお絵描き画像は私が投稿したお絵描きなので、今度はコピーライトメッセージが表示されていません。下のお絵描き画像は私以外の利用者が投稿したものなので、私の ID でログインしていてもコピーライトメッセージが表示されます:
2023060402


各お絵描き画像を詳細画面で見た場合です。私のお絵描き画像にはコピーライトメッセージがなく、他ユーザーのお絵描き画像にはコピーライトメッセージが上書きされて、それぞれ表示されていることがわかります:
2023060403



2023060404


繰り返しますがログイン前後で画像表示部分の HTML は変わっていませんが、ログインの有無によって同じ REST API の返り値が変わる形で実装しているので、画像データそのものの取得はシンプル(<img src="xxxx" /> 部分はログイン前後で全く同じ)です。しかしここがシンプルなだけに、画像表示部分の HTML や JavaScript を見られたとしても、投稿したユーザーの ID でログインしない限りはオリジナル画像を取得する方法がない、という形で実装できたことになります。


最初は「どうやってオリジナル画像の情報を隠そうか」と色々な実現方法を考えていたのですが、スクリーンショット対策の「オリジナル画像ではない画像を表示する」というアイデアを応用させる形でこの方法を思いつきました。この方法は上でも書いている通り「キャッシュを有効にできない」という弱点はあるものの、(自分のように笑)そこまでアクセスの多くないログイン付きサービスで、API 取得以外の方法で画像にアクセスできないようにすることができれば、投稿者本人だけはオリジナル画像に簡単にアクセスできるというメリットまで含めて、この実装方法はかなり現実的なものになり得ると考えています。

これで投稿者のオリジナル画像の無断コピーを(投稿者本人以外からは)絶つことができそう、と思う。近いうちにマンホールマップにもこの実装を移植しよ。

※回避できるツワモノがいらっしゃったら教えてください。 m(__)m



最初にお断りを。今回紹介するサービスはソースコードを提供していますが、実際にブラウザから使える便利なサービスの形では提供していません(理由は後述します)。実際に試すには環境を準備の上、ソースコードを各自の PC で実際に動かしていただく必要があります。ご了承ください。なおこちらでの動作確認は Windows10 + WSL2 + Ubuntu 18.04(20.04) の Python 及び Node.js で行っています。


今回のブログエントリで紹介するのは「画風変換」サービスです。サービスといってもウェブで公開しているわけではなく、公開しているソースコードを元に自分の PC で動かす必要があるので、実際に変換するまでのハードルは少し高めの内容です。


【画風変換とは?】
耳慣れない言葉だと思います。画風変換そのものは PFN のこのページで紹介されている内容がわかりやすいので、まずはこちらを一度参照ください(今回紹介するサービスも内部的にここで紹介されているツールを使っています):
画風を変換するアルゴリズム


ニューラルネットを使って実装されたアルゴリズムの論文を Python で実装した様子が紹介されています。誤解を恐れずに簡単な説明をすると、2枚の画像を用意して、うち1枚(コンテンツ画像)に写っている物体の形や配置をそのままに、もう1枚(スタイル画像)の色使いやタッチの特徴といった「画風」を適用するように変換して新しい画像を生成するアルゴリズムです:
2021060902


上述のページには同じ猫のコンテンツ画像に様々なスタイル画像を適用して画風変換した例が複数紹介されています:
2021060903


ここで紹介されている画風変換を実現するためのツール : chainer-gogh はソースコードが公開されています:
https://github.com/mattya/chainer-gogh


【「自分のお絵描きで画風変換する」とは?】
今回のブログエントリで紹介するのは「自分のお絵描きをスタイル画像にして画風変換するサービス」です。私が開発&公開しているお絵描きサービス MyDoodles を上述の chainer-gogh と組み合わせて使えるようにしたものです。具体的には画風変換には2枚の画像が必要ですが、コンテンツ画像は自分でアップロードした画像(写真を想定しています)、そしてスタイル画像は MyDoodles を使って描いたお絵描き画像を指定して画風変換する、というものです。画風変換はコンテンツ画像に写真、スタイル画像に絵を指定すると不思議な感じの絵が生成されることが多いのですが、このスタイル画像として自分のお絵描きを適用して画風変換を実現できるようにしたものです。


【ツールをウェブサービスとして公開しない理由】
理想を言えば、このツールをウェブで公開して誰でも気軽に使えるようにしたかったのですが、今回それは諦めました。後述で紹介する方法を実践して、自分の PC で試しに動かしてみるとわかると思うのですが、この画風変換は CPU に非常に大きな負荷をかける処理で、画風変換が完了するまでにかかる時間は、動かす PC のスペックにもよりますが、かなりいいスペックの PC でも1つの処理に対して1時間程度は覚悟※しておく必要があります。

※ GPU を搭載した機種であれば GPU を使って処理すればかなり高速化できると思いますが、それでも数10分間は負荷 100% の状態が続くと思います。

要はそこそこの PC を用意して1つの処理に集中させても1時間程度は負荷 100% が続くような処理なのです。これをウェブで公開して、複数の処理を同時に・・・となった場合の負荷や処理時間が想像できませんが、間違いなくタイムアウトとの戦いになるはずです。 こんな事情もあって、今回はウェブでの公開を諦め、「自分の PC で自分用の画像変換専門に行う」ツールとして公開することにしたのでした。


【ツールのセットアップ】
では実際に画風変換を行うにあたっての、事前セットアップの手順を紹介します。大きく chainer-gogh を動かすためのセットアップと、ウェブのフロントエンドアプリを動かすためのセットアップの2つに分かれていて、手順としては(0)事前準備、(1)フロントエンドアプリのソースコードを用意、(2)chainer-gogh のソースコードを用意、(3)chainer-gogh のセットアップ、(4)フロントエンドアプリのセットアップ、(5)コンテンツ画像とスタイル画像(お絵描き画像)の準備、の順に行う必要があります。では以下で順に紹介します。

(0)事前準備
このサービス・ツールを動作させるために以下のプログラミング言語実行環境ランタイムが必要です:
- Python 3.x
- Node.js 12.x

自分の PC 環境でこれらのツールが使えるよう、事前にインストールしておいてください。

(1)フロントエンドアプリのソースコードを用意
今回のツールは以下のようなフォルダ構成となります:
|- chainer-gogh-webapp/
    |- chainer-gogh/ (chainer-gogh のソースコード)
    |
    |- webapp/       (フロントエンドアプリのソースコード)
    |

chainer-gogh のソースコードは手順(2)で用意することになるので、まずは chainer-gogh 以外のソースコード構成を用意します。

git clone または zip ダウンロードで、以下のソースコードを手元に用意してください:
https://github.com/dotnsf/chainer-gogh-webapp

正しく展開できると、以下のようなフォルダ構成が再現できます:
|- chainer-gogh-webapp/
    |- webapp/       (フロントエンドアプリのソースコード)
    |

次に残った chainer-gogh のソースコードを用意します。

(2)chainer-gogh のソースコードを用意

(1)で用意した chainer-gogh-webapp/ フォルダに移動してから以下を git clone するなどして、chainer-gogh-webapp/chainer-gogh/ を用意します:
https://github.com/mattya/chainer-gogh


これで以下のようなフォルダ構成になっているはずです:
|- chainer-gogh-webapp/
    |- chainer-gogh/ (chainer-gogh のソースコード)
    |
    |- webapp/       (フロントエンドアプリのソースコード)
    |

(3)chainer-gogh のセットアップ

では早速 chainer-gogh を動かして・・・と言いたい所ですが、実は chainer-gogh の公開ソースコードは少し古い所があり、最新の Python3 環境で動かすには少し変更を加える必要があります。具体的には以下2ファイルで5箇所を書き換えてください( - で始まる行を + で始まる行の内容に変更してください):
(chainer-gogh.py)

(13行目)
   13 : - from chainer.functions import caffe
   13 : + from chainer.links import caffe

(100, 101 行目)
  100 : - mid_orig = nn.forward(Variable(img_orig, volatile=True))
  101 : - style_mats = [get_matrix(y) for y in nn.forward(Variable(img_style, volatile=True))]
  100 : + with chainer.using_config("enable_backprop", False):
  101 : +     mid_orig = nn.forward(Variable(img_orig))
  102 : + with chainer.using_config("enable_backprop", False):
  103 : +     style_mats = [get_matrix(y) for y in nn.forward(Variable(img_style))]

(models.py) (5 行目) 5 : - from chainer.functions import caffe 5 : + from chainer.links import caffe (22 行目) 22 : - x3 = F.relu(getattr(self.model,"conv4-1024")(F.dropout(F.average_pooling_2d(F.relu(y3), 3, stride=2), train=False))) 22 : + x3 = F.relu(getattr(self.model,"conv4-1024")(F.dropout(F.average_pooling_2d(F.relu(y3), 3, stride=2)))) (74 行目) 74 : - y6 = self.model.conv6_4(F.relu(F.dropout(self.model.conv6_3(F.relu(self.model.conv6_2(F.relu(self.model.conv6_1(x5))))), train=False))) 74 : + y6 = self.model.conv6_4(F.relu(F.dropout(self.model.conv6_3(F.relu(self.model.conv6_2(F.relu(self.model.conv6_1(x5))))))))

ソースコードの変更が完了したら Python3 のライブラリを pip でインストールします(Python3 のインストール方法によっては "pip" の部分を "pip3" にする必要があるかもしれません):
$ cd chainer-gogh-webapp/chainer-gogh

$ pip install typing_extensions

$ pip install pillow

$ pip install chainer

chainer-gogh の準備の最後に学習済みモデルを用意します。(ダウンロードサイズと実行時の負荷が比較的小さいという意味で)気軽に使える nin(Network in Network) Imagenet Model をダウンロードします:
https://gist.github.com/mavenlin/d802a5849de39225bcc6

2021060901

上記 URL から↑のリンクをクリックして nin_imagenet.caffemodel というファイルをダウンロードして(30MB ほど)、chainer-gogh/ フォルダに保存します。


(4)フロントエンドアプリのセットアップ

続けて Node.js 側のセットアップを行います。
$ cd chainer-gogh-webapp/webapp

$ npm install

(5)コンテンツ画像とスタイル画像(お絵描き画像)の準備

最後に画風変換を行う際のコンテンツ画像とスタイル画像を準備します。コンテンツ画像は画像ファイルであればなんでもいいのですが、絵よりは写真の画像を用意することをおすすめします。今回は「フリー素材アイドル」である MIKA☆RIKA さんの、以下の画像を使わせていただくことにします:
mikarika


次にスタイル画像となるお絵描き画像を用意します。一応サンプル的なものは用意されているので自分でお絵描きをする必要はないのですが、自分のお絵描きがスタイル画像となって画風変換することが楽しいと思っているので、是非挑戦してみてください(笑)。


PC ブラウザかスマホブラウザを使って(スマホがおすすめ)以下の URL にアクセスしてください:
https://mydoodles.mybluemix.net/
2021060904


指でお絵描きができるサービスです。色や線の太さ、背景色を指定して描いたり、アンドゥ・リドゥ・リセット程度のリタッチが可能です。PC ブラウザから利用している場合は指の代わりにマウスで描いてください。最後に「保存」ボタンで保存します。なお画風変換のスタイル画像として利用する場合は背景色の指定をしておいたほうが変換後のイメージがスタイルに近づくと思っています(背景が不要の場合でも背景色に白を明示的に指定して描いてください。透明なままだとスタイル変換時に黒くなってしまうようなので):
2021060906


自分が描いた画像はトップページの「履歴」ボタンから参照可能です:
2021060904


スタイルとして使いたい画像を1つ選んで表示します:
2021060905


この時の URL を参照します。URL の最後に /doodle/xxxxxxxxxx という部分があるはずなので、この /doodle/ に続く最後のパラメータの値(xxxxxxxxxx)が後で必要になるのでメモするなどしておいてください:
2021060907


これで画風変換を行うための準備が整いました。


【画風変換】
では実際に画風変換してみましょう。まずは webapp フォルダでフロントエンドアプリケーションを起動します:
$ cd chainer-gogh-webapp/webapp

$ node app

これがデフォルトの起動方法ですが、この方法だと 'python' というコマンドで Python3 が(内部的に)実行されます。セットアップ手順によっては Python3 コマンドが 'python3' というコマンド名になっていることもありますが、その場合は node 実行時の環境変数 python で Python3 が実行されるコマンド(この例だと python3)を指定しながら起動してください:
$ cd chainer-gogh-webapp/webapp

$ python=python3 node app

フロントエンドアプリケーションの起動に成功すると 8080 番ポートで待ち受けるので、PC のウェブブラウザで http://localhost:8080/ にアクセスします:
2021060901


この画面中央に3列からなる表示エリアがあります。一番左に画風変換を行うコンテンツ画像、真ん中がスタイル画像、そして右に画風変換の結果が表示されることになります。デフォルトでスタイル画像が表示されていますが、これは僕が描いたもので、これをそのままスタイル画像として使うこともできます。が、せっかくなので自分で描いた画像に変えてから画風変換を実行していただくことを想定しています&おすすめします:
https://mydoodles.mybluemix.net/doodle/0175dcf0-c045-11eb-8c4e-8de1dabb1b17
2021060902


スタイル画像を変更にするには、MyDoodles で描いたお絵描きの URL 最後のパラメータの値(上述例だと 0175dcf0-c045-11eb-8c4e-8de1dabb1b17)を sub と書かれた下のフィールドにコピー&ペーストしてください。

例えば、このお絵描きをスタイル画像に指定する場合であれば、パラメータは 63e083b0-c345-11eb-8c4e-8de1dabb1b17 なので、sub の下のフィールドに 63e083b0-c345-11eb-8c4e-8de1dabb1b17 と入力します:
2021060903


するとこのようにフロントエンドのスタイル画像が指定したお絵描きに切り替わります:
2021060904


次にコンテンツ画像を指定します。こちらは直接アップロードする必要があるので、main と書かれた下のボタンをクリックして、自分の PC からコンテンツ画像として使いたい画像ファイルを指定します。今回は上述の MIKA☆RIKA さんの画像を使うので、指定するとこのような画面になります:
2021060905


コンテンツ画像とスタイル画像の両方がプレビューされている状態になれば画風変換を実行できます。result と書かれた下にある「RESULT」ボタンをクリックして画風変換がスタートします。

PCのスペックにもよりますが、画風変換には非常に長い時間がかかります。result 欄にはその画風変換の途中経過が少しずつ表示されていきます:
2021060901
  ↓
2021060902
  ↓
2021060903


またこの途中経過画像は chainer-gogh-webapp/chainer-gogh/output_dir/(指定したパラメータ名)/ というフォルダの中に随時作成されていきます。このフォルダの中を見ていると、元のコンテンツ画像にスタイル画像の画風が少しずつ適用されて、輪郭がはっきりしていく様子が確認できます。これはこれで見ていて面白いです:
2021060904



画像は im_00000.png, im_00050.png, im_00100.png, im_00150.png, .. と "50" 刻みで増えていき、im_04950.png まで 100 段階 100 枚が作成された段階で(このアプリケーションでの)画風変換は終了となります:
2021060905


今回のコンテンツ画像とスタイル画像での画風変換は最終的にこのような結果(右)になりました。適当にお絵描きした○ールおじさんの画風(?)が MIKA☆RIKA さんの写真に適用できていますよね。元の画像やお絵描きを指定している点で人手は入っていますが、これは「人工知能が描いた世界に一枚の絵」という表現ができるものです:
20210609_mikarika_0.5


同じコンテンツ画像で、スタイル画像を替えて実行した結果はこんな感じでした。スタイル画像の違いが結果の違いにあらわれている様子が確認できると思います:
20210608_mikarika_0.5


ちなみにこの画風変換にかかる処理時間(最後の画像が作られるまでの時間)ですが、Intel i7-7500 2.7GHz の4コア CPU でメモリを 16GB 搭載した Windows 機で他の処理を何もせずに実行した場合でおよそ1時間といったところでした。環境によってかかる時間は前後すると思いますが、1つの参考になれば。

この処理時間を短縮するため、GPU 搭載機種であれば GPU を使って高速に処理できるよう改良中です。Windows から直接実行する場合だとうまくいくかもしれないのですが、WSL を挟んで実行しようとするとなかなかうまくいかず・・・また GPU を使うのであれば利用モデルも別のものにしたほうがいいと思われる、など、こちらは現時点ではまだまだ検討段階含めて未実装ということで。


ともあれ、いちおう動く状態のフロントエンド付きサービスにはなっていると思います。環境構築の手間がちと大変かもしれませんが、ぜひ自分(やご家族)でお絵描きした結果を、自分で撮った写真のスタイルに適用するなどして楽しんでいただければと思っています。


まだコードに手を加えることもあり、開発中ゆえの不安定さもあるのですが、一応一通りの機能が動く状態になったのでサービスを公開します(2020/05/19)。


自作のお絵描き共有サービス MyDoodlesNintendo Switch の人気アプリ「あつまれ どうぶつの森」のマイデザイン化するための機能を実装しました。とりあえずは手持ちの Windows 10 PC および iPhone SE で動作確認しています。


【はじめに】
最初にお断りをしておくと、このサービスの編集機能そのものはそれほど強力ではありません。線の色や太さを選んで描画する以外には、背景色設定と、アンドゥ、リドゥ、リセット程度の機能しかありません。一般的なレタッチアプリのような細かな編集はできませんが、よく言えば「簡単」「気軽」です。小学校低学年程度の子供でも利用できることを想定して開発しています(その割には漢字とかも使ってるけど・・ (^^;)。

また「そもそもなんでこんなツールを作ったのか?」を説明します。「あつまれ どうぶつの森」にはマイデザインを編集する機能が標準で付属していて(ゲーム内でマイルを貯めて機能豊富な Pro エディタを使うことも可)自分の好きなデザインを作ることはできますが、これがちと使いづらいというか何というか・・・だったりします:
EYXVHfAUwAAz0tb


このような状況に対して僕と同じような考えを持っている人が少なからずいるようで、後述のようなより便利にデザインを編集できるサービスがいくつか公開されていたりします。自分も先人達から提供いただいた情報を頼りに、その流れに乗っかる形でサービスを開発してみました。ただ自分の場合はデザインは専門ではなく、自分向けという意味もあるのですが「より自由度高くデザインする」というよりは「より簡単に使える」ことを目指して作ってみました。

なお今回作成したツールでは「指でお絵描き」する作業がありますが、この部分の実現には自分が開発した doodlejs を改良して使っています。この doodlejs の応用で LINE で手書きスタンプを送ったり、大勢でお絵描きをした内容を同時に参照したりしています。応用範囲の大きなライブラリだと思っていて、今回のサービスも doodlejs の応用で実現しています:
2020051901


・・・以上、宣伝コーナーでした(笑)。

では以下で MyDoodles の使い方を説明し、続けてマイデザイン化するための手順を紹介します。


【MyDoodles の使い方】
MyDoodles 自体は PC、スマホ、タブレットのウェブブラウザを使って URL にアクセスすることで利用できます(ただし後述のマイデザイン化する場合は PC のマウスで描画するよりも、スマホを使って指で描画する方が簡単だと思っています。以下のスクリーンショットもスマホでのものを中心に紹介します):
https://mydoodles.mybluemix.net/



アクセスすると以下のような画面が表示されます:
2020051900



それぞれ以下のような役割を持っています:
2020051901


タイトル絵のタイトル
履歴同一端末で過去に保存した絵を呼び出す
線の色描画する線の色
線の太さ描画する線の太さ
背景色タップすると「線の色」で指定された色をキャンバスの背景色にする
キャンバスここにお絵描きを描画します
アンドゥ1ストローク戻る
リセットキャンバスを初期状態に戻す
保存キャンバスのお絵描きを保存する
リドゥ(アンドゥ後に)1ストローク進める



タイトル欄には絵のタイトルを入力します。後述のマイデザインにする場合、ここで指定した内容が絵のタイトルにもなります:
2020051902


キャンバス画面を使って指で絵を描いていきます(PC を使っている場合はマウスやペンタブレットが使えます。タッチスクリーン対応の PC であれば画面に直接指でスクリーンに描くこともできます)。なお後述のマイデザイン化を想定する場合はあまり細い線で描いても最終的に潰れてしまう可能性が高い(マイデザインは 32x32 サイズ)ので、太さ 10 以上の線で描くことをおすすめします。また PC ブラウザを使う場合は線の太さに加えて、なるべくキャンバス部分が正方形になるようウィンドウサイズを調整してから描くことを推奨します(マイデザインが正方形のため):
2020051903



最後に「保存」ボタンをクリックするとお絵描き内容が保存されます:
2020051907



保存されたお絵描き内容が表示されます:
2020051905


この画面から Twitter や facebook などの SNS にシェアすることができるようになり、シェアされた他の人も同じ画像を見ることができるようになります。なお同一端末(お絵描きを描いて保存した時に使っていた端末)からこの内容を表示している場合のみ、画面右上に「再編集」ボタンが表示され、このお絵描き内容を元に編集を続けることもできます。また「自分も試す!」ボタンはこのページをシェアされて見た人が自分でもお絵描きを試せるよう新規作成画面へ案内するボタンです:
2020051906


加えて、これはあまり使われない機能であると想定していますが、過去作品履歴情報の他機種への引っ越し機能も一応用意しています。手順はこのブログの一番下※に記載しておきます。


基本的なお絵描き共有サービスの機能は概ねこんな感じです。これはこれで簡単にお絵描きして、簡単に SNS でシェアできる、というものだと思っています。


【どうぶつの森 マイデザイン化】
MyDoodles サービスを使って作ったお絵描きの内容を「あつまれ どうぶつの森」のマイデザインとして取り込む手順を紹介します。なお、こちらの手順はお絵描きの作者本人だけでなく、シェアされたお絵描きページを見ている全ての人が実行可能です。またこの手順はスマホで行う必要はなく、(シェアされたお絵描きページの URL がわかっていれば)PC などから行うこともできますし、その方が楽だと思っています。

まず、この機能を使ってマイデザインを取り込むには Nintendo Switch Online アプリをスマホにインストールし、デザインを読み取る人のアカウントで初期設定しておく必要があります。あらかじめご用意ください:
2020051903



改めてお絵描き内容をマイデザイン化するまでの手順を紹介します。MyDoodles サービスのお絵描きページを表示して、そしてその中の「QR コード」ボタンをタップします:
2020051901


すると画面内にお絵描き内容の情報を含む QR コードが表示されます:
2020051902


この QR コードを Nintendo Switch Online アプリの「あつまれ どうぶつの森」サービス内「タヌポータル」の「マイデザイン」から読み込みます:
2020051904


この手順を実行するには上述の QR コードをスマホの Nintendo Switch Online アプリを起動して読み取ることになります。したがってNintendo Switch Online アプリをインストールしたスマホとは別のスマホや方法で上記 QR コードを表示する必要があります。別のスマホや PC を使って MyDoodles から表示するか、 QR コードの内容をスクリーンショットで撮影して別途写真共有サービスなどを使うなどして、Nintendo Switch Online アプリのタヌポータル「マイデザイン」から生成された QR コードを読み込んでください:
2020051905


正しく QR コードが読み取れると以下のような確認画面になります(32x32 に縮小された結果、どの程度潰れてしまうかを確認できると思います)。読み込む場合は「保存」します:
2020051906


これで MyDoodles で描いたお絵描き内容が「あつまれ どうぶつの森」から取り込めるようになりました:
2020051907


ここから先は「あつまれ どうぶつの森」を実際に起動して行う操作となります。


「あつまれ どうぶつの森」を起動後に、(ゲーム内の)スマホを取り出し、「マイデザイン」を選択します:
2020051908


マイデザインの一覧が表示されている画面で「ダウンロード(+ボタン)」を選択し、インターネットに接続して「ダウンロード」を選択します:
2020051900


上述の作業で QR コードから取り込んだデザインがダウンロードされます。ダウンロードする先のデザイン(白紙のデザインか、上書きしてよいデザイン)を選んで保存します:
2020051901


MyDoodles で作ったお絵描きがマイデザインとして保存されました:
2020051902



現在の仕様では保存したマイデザインは「あつまれ どうぶつの森」の中では再編集することはできませんが、トップスとして身につけたり、地面に敷いたりする、等といったことができるようになります:
2020051903


2020051909



と、以上が MyDoodles サービスの簡単な使い方、およびマイデザイン対応の手順となります。繰り返しますが凝ったデザインを描くためのツールというよりは、気軽にお絵描きしたものがゲーム内で使えることを主目的としている点をご了承ください。


なお、このツール(のマイデザイン対応)の開発をするにあたり、以下のサイトの情報を大変参考にさせていただきました。ありがとうございます。 特に「ドット絵ナニカ」は画像を指定してマイデザインを作る、というもので、凝ったデザインを作りたい人にとっては(デザインツールで凝った画像を作って変換すればよいので)こちらを使われた方が目的にあっていると思っています:
ドット絵ナニカ
「あつまれ どうぶつの森」のマイデザインのQRコードを写真・画像ファイルから生成する方法





過去作品履歴の引っ越し手順

この MyDoodles では作った作品をシェアして他の人に見せたりすることはできますが、原則として「同一機種で作った作品のみ」履歴一覧から参照して検索したり、再編集することができます。

ただ機種変更などの都合により、ずっと同じ機種を使うことができないことも想定されます。そんな場合にこの引っ越し手順により、他機種へ過去作品履歴を引き継ぐことができるようになります。ただし特に画面サイズの異なる他機種へ引っ越しした場合は、再編集時にうまく表示できなくなります。事実上、参照のみのための引っ越しと考えてください。

引っ越しするには引っ越し元と引っ越し先両方の 機種 ID が必要になります。機種 ID は履歴参照時に表示される赤枠の部分です:
2020051902


引っ越しは①引き継ぎ先指定、②取り込み元指定 の2段階からなります。まず引っ越し元となる機種で①を実行して引き継ぎ先機種の機種 ID を指定し、続けて引っ越し先となる機種で②を実行して引き継ぎ元機種の機種 ID を指定して取り込みます:
2020051903


②までが完了すると、引っ越し元機種からは履歴一覧を見ても過去作品は見えなくなります。



このページのトップヘ