• ベストアンサー

複数枚画像の合成

こんにちわ、Visual Studio 2005のフォームアプリケーションでプログラミングしているものです。複数枚の画像を一つの画像にしたいのですが、どうもあっているのかどうかわかりません。 たとえば、画像が9枚あって1枚目の一番左上の画素を[0-0,0]とすると、 [0-0,0][1-0,0][2-0,0]|[3-1,0][4-1,0][5-1,0]|[6-2,0][7-2,0][8-2,0] [0-0,0][1-0,0][2-0,0]|[3-1,0][4-1,0][5-1,0]|[6-2,0][7-2,0][8-2,0] [3-0,0][4-0,0][5-0,0]|[6-1,0][7-1,0][8-1,0]|[0-2,0][1-2,0][2-2,0] [3-0,0][4-0,0][5-0,0]|[6-1,0][7-1,0][8-1,0]|[0-2,0][1-2,0][2-2,0] [6-0,0][7-0,0][8-0,0]|[0-1,0][1-1,0][2-1,0]|[3-2,0][4-2,0][5-2,0] [6-0,0][7-0,0][8-0,0]|[0-1,0][1-1,0][2-1,0]|[3-2,0][4-2,0][5-2,0] -----------------+-----------------+------------------------ [0-0,1][1-0,1][2-0,1]|[3-1,1][4-1,1][5-1,1]|[6-2,1][7-2,1][8-2,1] [0-0,1][1-0,1][2-0,1]|[3-1,1][4-1,1][5-1,1]|[6-2,1][7-2,1][8-2,1] [3-0,1][4-0,1][5-0,1]|[6-1,1][7-1,1][8-1,1]|[0-2,1][1-2,1][2-2,1] [3-0,1][4-0,1][5-0,1]|[6-1,1][7-1,1][8-1,1]|[0-2,1][1-2,1][2-2,1] [6-0,1][7-0,1][8-0,1]|[0-1,1][1-1,1][2-1,1]|[3-2,1][4-2,1][5-2,1] [6-0,1][7-0,1][8-0,1]|[0-1,1][1-1,1][2-1,1]|[3-2,1][4-2,1][5-2,1] -----------------+-----------------+------------------------ [0-0,2][1-0,2][2-0,2]|[3-1,2][4-1,2][5-1,2]|[6-2,2][7-2,2][8-2,2] [0-0,2][1-0,2][2-0,2]|[3-1,2][4-1,2][5-1,2]|[6-2,2][7-2,2][8-2,2] [3-0,2][4-0,2][5-0,2]|[6-1,2][7-1,2][8-1,2]|[0-2,2][1-2,2][2-2,2] [3-0,2][4-0,2][5-0,2]|[6-1,2][7-1,2][8-1,2]|[0-2,2][1-2,2][2-2,2] [6-0,2][7-0,2][8-0,2]|[0-1,2][1-1,2][2-1,2]|[3-2,2][4-2,2][5-2,2] [6-0,2][7-0,2][8-0,2]|[0-1,2][1-1,2][2-1,2]|[3-2,2][4-2,2][5-2,2] といった感じにしようと思っています。 画像には配列を使っていてbmp[0]~[8]が9枚の画像を表し、picはbmp[0]~[8]の画像一枚に対してサイズが横3倍縦6倍の画像になるはずです。 自分でプログラムしたのですが、できた画像を拡大しても細かすぎてよくわからない状況です。 for ( y = 0; y < h; y += 6 ) {  for ( x = 0; x < w; x += 3 ) {   for( b = 0; b < 3; b++ ) {    for( a = 0; a < 3; a++ ) {      pic->SetPixel( x + a, y + (2 * b) , bmp[((2 * b) * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) );      pic->SetPixel( x + a, y + (2 * b) , bmp[(((2 * b) + 1) * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) );    }   }  } } 以前に、同じような配置法なのですが横3倍縦3倍の合成画像として、 [0-0,0][1-0,0][2-0,0]|[3-1,0][4-1,0][5-1,0]|[6-2,0][7-2,0][8-2,0] [3-0,0][4-0,0][5-0,0]|[6-1,0][7-1,0][8-1,0]|[0-2,0][1-2,0][2-2,0] [6-0,0][7-0,0][8-0,0]|[0-1,0][1-1,0][2-1,0]|[3-2,0][4-2,0][5-2,0] -----------------+-----------------+------------------------ [0-0,1][1-0,1][2-0,1]|[3-1,1][4-1,1][5-1,1]|[6-2,1][7-2,1][8-2,1] [3-0,1][4-0,1][5-0,1]|[6-1,1][7-1,1][8-1,1]|[0-2,1][1-2,1][2-2,1] [6-0,1][7-0,1][8-0,1]|[0-1,1][1-1,1][2-1,1]|[3-2,1][4-2,1][5-2,1] -----------------+-----------------+------------------------ [0-0,2][1-0,2][2-0,2]|[3-1,2][4-1,2][5-1,2]|[6-2,2][7-2,2][8-2,2] [3-0,2][4-0,2][5-0,2]|[6-1,2][7-1,2][8-1,2]|[0-2,2][1-2,2][2-2,2] [6-0,2][7-0,2][8-0,2]|[0-1,2][1-1,2][2-1,2]|[3-2,2][4-2,2][5-2,2] の配置プログラムとして、 for ( y = 0; y < h; y += 3 ) {  for ( x = 0; x < w; x += 3 ) {   for( b = 0; b < 3; b++ ) {    for( a = 0; a < 3; a++ ) {      pic->SetPixel( x + a, y + b , bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 3 ) );    }   }  } } との回答をいただいたので、これを参考に作ってみたのですが・・・。 説明が下手でわかりにくいかもしれませんが、お分かりの方がいましたらご教授お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>     pic->SetPixel( x + a, y + (2 * b) , bmp[((2 * b) * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) ); >     pic->SetPixel( x + a, y + (2 * b) , bmp[(((2 * b) + 1) * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) ); 間違ってる。 偶数ラインと奇数ラインは、同じbmpから同じデータを持って来るはず。 なので、3つ目の引数は、2行とも同じにならないとおかしい。 そして「縦が6倍でも、縦が3倍でも、持って来る方法は同じ」じゃないといけない(但し、yの増加が3から6になってるので、そこだけ変更しないといけない) また「横は変わってない」「持って来る方法は同じ」なのだから「縦3倍と縦6倍の時で、1番目と3番目の引数は同じ」にならないとならない。 つまり「変えるは2番目の引数だけ」になる。 3倍の時が      pic->SetPixel( x + a, y + b , bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 3 ) ); だったのなら、6倍の時は「2番目の引数だけ変える」のだから偶数ラインは      pic->SetPixel( x + a, ???, bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) ); になる筈。 奇数ラインは偶数ラインの1ライン下だから      pic->SetPixel( x + a, ??? + 1, bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) ); になる筈。 で、6倍のプログラムは、yは6づつ増えてて、bは1づつ増えてる。 y、b、偶数ラインの位置、奇数ラインの位置を表にすると y b 偶数ラインの位置 奇数ラインの位置 0 0 0              1 0 1 2              3 0 2 4              5 6 0 6              7 6 1 8              9 6 2 10              11 12 0 12              13 12 1 14              15 12 2 16              17 となる。 この表に合うように「???」の式、「??? + 1」の式を書けば良い事になる。 すると「???」は「y + b * 2」だと判る。 上記を踏まえて書き直すと for ( y = 0; y < h; y += 6 ) {  for ( x = 0; x < w; x += 3 ) {   for( b = 0; b < 3; b++ ) {    for( a = 0; a < 3; a++ ) {      pic->SetPixel( x + a, y + b * 2, bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) );      pic->SetPixel( x + a, y + b*2+1, bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 ) );    }   }  } } となる。 しかし「同じデータを2度取り出す」のだから「取り出すのは1回」で良い筈。 従って TColor col; for ( y = 0; y < h; y += 6 ) {  for ( x = 0; x < w; x += 3 ) {   for( b = 0; b < 3; b++ ) {    for( a = 0; a < 3; a++ ) {      col = bmp[(b * 3 + a + x) % 9]->GetPixel( x / 3, y / 6 );      pic->SetPixel( x + a, y + b * 2, col);      pic->SetPixel( x + a, y + b*2+1, col);    }   }  } } とすれば良い。

judas15
質問者

お礼

分かりやすい説明ありがとうございます。 拡大してみると、ちゃんとした画像ができているのがハッキリわかりました。 縦だけではなくて、横も変えてみた結果うまくいきました。 ありがとうございます。

その他の回答 (1)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

元が9枚しかない画像で24倍の画像を作るのでしょうか? 3x3ならば9倍ですから9枚の画像から生成しても隙間は出来ません 元が2x2ぐらいのマトリックスでどのように配置するのか提示してみましょう

judas15
質問者

お礼

回答ありがとうございます。 縦を2倍にして、横はそのままの1倍にしようとしていました。 なので結果的には元画像(例えばbmp[0])の縦6倍、横3倍の画像を作ろうとしていたわけです。 縦に同じ画像の画素を2つづつ配置しています。 やっぱり、説明わかりにくかったですね・・・すみません。 今回は別の方に詳しい説明をいただいた結果画像がしっかり生成されました。 せっかく回答いただいたのにすみません、いつもありがとうございます^^

関連するQ&A