5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

フォトモザイクやりたいな〜その1

Posted at

はい、今回は画像周り。
最近数年やらなかったことをまとめて叩き込んでおります。
できることは増やしておかないとね。

画像の平均値とか色と色の距離とか。
最終的にやりたいのはフォトモザイク。えっと、一枚の画像があって、それのいろをもとに
例えばtwitterのフォローアーの画像で元の絵になるようにならべたりとかするやつ。
今回は元絵の平均色だすところとかまで。
平均色は全部足して割ればいいから簡単。
なぜにUnityでやる?ときかれればmacにFlashいれてないから・・・。phpのローカル開発環境もいれてないからいちいちサーバーにあげてテストするのもめんどくさいのです。という個人的な理由です。

こんなカラフルな画像があって、500*500
スクリーンショット 2016-09-08 10.17.51.png

10 *10だと
スクリーンショット 2016-09-08 10.18.11.png

20*20
スクリーンショット 2016-09-08 10.17.56.png

50*50
スクリーンショット 2016-09-08 10.20.36.png

になるようにしたよというだけ。

とりあえず簡単に縦横が同じサイズのもののみしか考慮しないでやってみたところ。

	public RawImage baseImg;
	public RawImage resultImg;
	public Texture2D baseTex;

	void Start () {
		int w = baseImg.texture.width;
		int h = baseImg.texture.height;

		int cellCount = 50;
		int cellSize = w / cellCount;

		Texture2D avarageTex = new Texture2D(cellCount, cellCount, TextureFormat.RGBA32, false);
		int xIndex = 0;
		int yIndex = 0;
		for(int y = 0; y < h; y += cellSize)
		{
			xIndex = 0;
			for(int x = 0; x < w; x += cellSize)
			{
				Color c = GetAvarageColor(baseTex, x, y, cellSize, cellSize);
				avarageTex.SetPixel(xIndex, yIndex, c);
				xIndex++;
			}
			yIndex++;
		}
		avarageTex.Apply();
		resultImg.texture = avarageTex;

	}

	// 1ます分の平均色を計算
	private Color GetAvarageColor(Texture2D tex, int startX, int startY, int cellWidth, int cellHeight)
	{
		float rrr = 0;
		float ggg = 0;
		float bbb = 0;

		for(int y = startY; y < startY + cellHeight; y++)
		{
			for(int x = startX; x < startX + cellWidth; x++)
			{
				Color c = tex.GetPixel(x,y);
				rrr += c.r;
				ggg += c.g;
				bbb += c.b;
			}
		}

		rrr /= (float)cellWidth * (float)cellHeight;
		ggg /= (float)cellWidth * (float)cellHeight;
		bbb /= (float)cellWidth * (float)cellHeight;

		return new Color(rrr, ggg, bbb, 1);
	}

この続きはなんか適当に大量の同じサイズの画像とかを用意して、
事前に平均の色を計算させておき、それをテキストか何かにまとめておく。
ここまでは事前にやっておかないと、表示まで時間かかっちゃうもんね。
あとは先ほどの計算したブロッグごとの色を元にたくさんの画像から色の近い順ものを当てはめていく。
色と色の距離は三平方の定理?みたいなのでもとめられるのでこれが近いものをセットしてあげれば完成するはず。

とりあえず画像を調達しにflickrからとりあえず100枚ぐらい適当にダウンロードしてきて、
automatorさんに200px*200pxとかのサイズにしてもらった。100枚とかでたりるかな・・・・って気もするけどいいや。
デスクトップに吐き出して途中NOOOOOO!ってなったりしたけど。ちゃんと片付けました。
スクリーンショット 2016-09-08 10.55.24.png

次は各画像ごとの平均色をまとめたファイルとか作る作業
フォーマットは画像名:平均色r,g,b みたいなかんじでいいかな。

まぁとりあえずこんな感じで・・・。

	public string pathImgList;

	void Start () {
		pathImgList = Application.dataPath + "/Resources/Texture";
		StreamWriter sw = null;
		FileInfo fi;
		fi = new FileInfo(Application.dataPath + "/Resources/imgData.txt");

		// .metaがはいってしまうので.jpgのみに絞る
		string[] imgPathList = Directory.GetFiles( pathImgList, "*.jpg");
		int imgCount = imgPathList.Length;
		for( int i = 0; i < imgCount; i++ )
		{
			var s = File.ReadAllBytes(imgPathList[i]);
			Texture2D tex = new Texture2D(2, 2);
			tex.LoadImage(s);

			int w = tex.width;
			int h = tex.height;

			Color c = GetAvarageColor(tex, 0, 0, w, h);

			sw = fi.AppendText();

			sw.WriteLine(imgPathList[i].Replace(pathImgList + "/", "") + ":" + c.r + ","+ c.g + ","+ c.b );


			Debug.Log(imgPathList[i] + ":" + c);
			sw.Flush();
			sw.Close();
		}
	}

実行するとこんな感じのファイルが出力される。
あとは気合だね。うん、最初から気合だったね。
スクリーンショット 2016-09-08 15.39.29.png

一旦ここまで。

5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?