Twitterの画像をクリックしたら浮かび上がる画像を作ってみた

過去のブログのアーカイブ
この記事は前身のブログのアーカイブを引き継いだものです. 画像が正しく表示できないなど,コンテンツの表示に問題がある恐れがあります.

結構前に流行ってた気がする。画像をクリックすると浮かび上がる画像。
ただの単純な画像合成なのですが割と簡単にできるかも?

さていつもの前提条件なのですが、私は画像加工の技術が全然ないので合成はプログラマらしくコードを書いての合成です。
特別なソフトは使ってないつもりです。

完成形

最初に完成形の紹介をしておきます。その方がわかりやすいかと思って
twtr-img-ukabiagaru1
 
これが
twtr-img-ukabiagaru2
 
このようになります。
これは、通常の表示だと画像の背景が白なのですが、画像をクリックすると背景が黒になることが原因となっています。

工程

元画像の用意

まずは元画像の用意なのですが、浮かび上がると感動できうような画像にしたいですよね。というわけで、昔見てたアニメで思いついたのがらき☆すたのこなたの母。

元画像

元画像

まず画像を選ぶポイントは、浮かび上がると感動できる(?)物/人物の背景が白か黒に近い色であること。
不自然ない感じに加工するとなると、どちらかに塗りつぶしたほうがやりやすい感じです。
今回の画像だと壁の色は白に近いので、後からこれを白にベタ塗りにしてもそこまで不自然じゃないですよね

人物/ものを消す

次は人物/ものをペイントツール等を使って消します。その際に、背景の色を白か黒にベタ塗りしましょう
私は高機能なペイントツールの持ち合わせがなかったのでWindows標準で入っているペイントツールでしてみました。複雑な画像じゃなかったらすぐできます。
vF32eDw-2
こんな感じ。
そしてこの白色の透過度を0に設定しましょう。普通の標準搭載のペイントツールではできないと思いますが、ある程度高性能なソフトならできるはず。
あと背景を透明にするのではなく、アルファ値を0にするほうです。
ちなみにC#で透過度を0にするプログラムのコードはこちら

static void Main(string[] args) {
    Bitmap bmp = new Bitmap("vF32eDw.png"); // 元画像
    for (int x = 0; x < bmp.Width; x++) {
        for (int y = 0; y < bmp.Height; y++) {
            Color c = bmp.GetPixel(x, y);
            if (c.R == 255 &&
                c.G == 255 &&
                c.B == 255)
                bmp.SetPixel(x, y, Color.Transparent);
        }
    }
    bmp.Save("test1.png");  // 加工済みを保存
}

 合成先の画像も準備する

さて、これで準備完了…というわけではないです。このあと、人物/ものがある状態で壁をベタ塗りしないといけないです。
さっきの画像で人物/ものを残しているだけです。が、これも大事。
vF32eDw
後は同じようにベタ塗った背景の色を透過度0にします。
プログラムのコードはさっきと同じ。ファイル名を変更してコンパイル、実行させましょう。

画像を合成する

先ほど作った画像を合成させましょう。
レイヤー機能付きのペイントソフトならできるはずです。
ですが私は持ち合わせがないので(以下略) またC#で書いた合成させるプログラムのコードを置いておきます。

static void Main(string[] args) {
    Bitmap bmp1 = new Bitmap("test1.png"); // 画像1
    Bitmap bmp2 = new Bitmap("test2.png"); // 画像2
    for (int x = 0; x < bmp1.Width; x++) {
        for (int y = 0; y < bmp1.Height; y++) {
            Color c1 = bmp1.GetPixel(x, y);
            Color c2 = bmp2.GetPixel(x, y);
            if (c1 != c2) {
                 int c = (c1.R + c1.G + c1.B) / 3;
                 bmp1.SetPixel(x, y, Color.FromArgb(c, 255, 255, 255));
              }
            else if (c1.A == 0) {
                bmp1.SetPixel(x, y, Color.FromArgb(255, 255, 255, 255));
            }
        }
    }
    bmp1.Save("test.png"); // 合成後
}

 完成

これで完成です。
こんな感じにできてたら成功です。

まとめ

こんな記事で参考になる人いるのか怪しいですが…理論的には簡単なので、レッツトライです。