TIL:ラスタ画像について


グラフィックベース-1


画素(Pixel)、赤、緑、青の3種類の発光素子を表すのに用いられる.この3つを1つのピクセルに組み合わせます.
どうして赤、緑、青の3色なの?答えは人の目に映る.人間の目が色を認識する原理と同じだ.網膜中の細胞は3色に対する反応によって色を識別する.
ラスタグラフィックは、複数の画素をリストすることによって画像を表示する方法である.1つのピクセルは、異なるRGB値を表します.
ピクセル値が100%の場合は白、0%の場合は黒です.
解像度(resolution)は、横x縦形式で表すことができる.マトリクス構造と見なすこともできるし,二次元配列形式と見なすこともできる.解像度が十分でない場合にラスタリングを行うと、ステップ現象が発生する可能性があります.
RGBの値を表し、実数の場合は0~1の値で色を表します.たとえば、赤は(1.0、0、0)と表示されます.しかし、多くの場合、符号なし整数で表される.このとき、赤は(255,0,0)と表示されます.RGB 3色の組み合わせで複数の色を作ることができます.RGBモデルでは255 x 255 x 255色が表示されます.
RGBで最も多く使われているのは透明度A(Alpha)を加えたRGBAカラーモデルですが、用途によってはHSV、XYZ、CMYKなどのカラーモデルも使えます.A自体は不透明なので、1-Aは透明になります.
なぜ各色の値を表す符号なし整数が0から255なのか.したがって、通常0〜255は合計1 Byteであり、RGB値は3バイトごとに1バイトの透明度値を含み、合計4バイトは色値を表す.

では、複数のPPM画像を作成して保存するプログラムを作成し始めましょう。


これは、まず作成するPPM画像ファイルのフォーマット例です.
自分で作りたいなら、注釈以外の部分.拡張子をtxtファイルに設定します.ppmに変えて貯蔵するのは簡単です.
P 3/asciiコードを用いたmagic numberと呼ばれる画像ファイルフォーマット
3/横x縦解像度
255/0~255の符号なし整数を使用してRGB色を表します.
255 0 0 0 255 0 0 0 255//Red, Green, Blue
255 255 0 255 255 255 0 0 0//Yellow, White, Black
コード(C+)
//using C++

#include <iostream>
#include <fstream>

using namespace std;

int main()
{
	ofstream ofile("example1.ppm");

	const int image_width = 2;
	const int image_height = 2;

	ofile << "P3\n" << image_width << " " << image_height << "\n255\n";

	ofile << 255 << " " << 0 << " " << 0 << " ";
	ofile << 0 << " " << 255 << " " << 0 << "\n";
	ofile << 0 << " " << 0 << " " << 255 << " ";
	ofile << 0 << " " << 0 << " " << 0 << "\n";
	ofile << flush;

	return 0;
}
以下のPPMイメージファイルが作成されます.

いくつかの応用


前の実習に比べて、これは少し難しいコードで、赤と青からなるPPM画像が生成されます.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>

using namespace std;

void writePPM(const string& filename, const int width, const int height, const vector<int> buf);

int main()
{
	const string filename = "example3.PPM";

	// make an image
	const int image_width = 128;
	const int image_height = 128;

	vector<int> buffer(image_width * image_height * 3);

	for (int j = 0; j < image_height; j++)
	{
		for (int i = 0; i < image_width; i++)
		{
			const int offset = ((i + image_height * j) * 3);
			if (i < (image_width / 2))
			{
				buffer[offset] = 255;
				buffer[offset+1] = 0;
				buffer[offset+2] = 0;
			}
			else
			{
				buffer[offset] = 0;
				buffer[offset + 1] = 0;
				buffer[offset + 2] = 255;
			}
		}
	}

	// write to file
	writePPM(filename, image_width, image_height, buffer);

	return 0;
}

void writePPM(const string& filename, const int width, const int height, const vector<int> buf)
{
	ofstream ofile(filename);

	ofile << "P3\n" << width << " " << height << "\n255\n";

	for (int j = 0; j < height;j++)
	{
		for (int i = 0; i < width; i++)
		{
			const int offset = ((i + width * j) * 3);
			for (int c = 0; c < 3;c++)
			{
				ofile << buf[offset + c];
				if (i < width - 1 || c < 2)
				{
					ofile << " ";
				}
			}
		}
		ofile << "\n";
	}
	ofile << flush;
}
相応の練習をするには、ある程度のC++文法の理解が必要です.