OpenGLで描画した画像のピクセル情報を配列に格納する方法

このQ&Aのポイント
  • OpenGLを使用して描画した画像のピクセル情報を取得するためには、glReadPixels()関数を使用します。
  • ただし、取得したRGBの値が描画したものと異なる場合があります。
  • glReadBuffer()およびglPixelStorei()を適切に設定する必要があります。
回答を見る
  • ベストアンサー

OpenGLで描画した画像のピクセル(RGB)を配列に格納したい。

初めまして。taka-0910と申します。 現在、OpenGLを使って描画した画像のピクセル情報を取得しようと考えています。 しかし、取得したRGBの値が描画したものとまったく異なる値となってしまいます。 glReadPixels()という関数で試していますが、何度修正してもうまくいきません。よろしくお願いします。 プログラムの一部ですがこのようになっています。プログラムが一部分で申し訳ありません width, heightというのは、画像のサイズです。 *pixelsに画素(RGB)の値を格納したいと考えています。 GLubyte *pixels; pixels = ( GLubyte* )malloc( width * height * 3 * (sizeof(GLubyte))); glReadBuffer(GL_FRONT); glPixelStorei( GL_PACK_ALIGNMENT,1 ); glReadPixels( 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels ); glFlush();

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

  • ベストアンサー
  • noocyte
  • ベストアンサー率58% (171/291)
回答No.1

念のために確認しますが,OpenGL ES じゃなくて OpenGL なんですか? OpenGL ES の glReadPixels() のマニュアルを読むと,format 引数に 何を指定しても RGBA フォーマットに変換して取得してしまうようです. いずれにせよ,とりあえず RGBA フォーマットでの取得を試してみては? OpenGL ES 1.0 の glReadPixels() のマニュアル http://www.khronos.org/opengles/documentation/opengles1_0/html/glReadPixels.html OpenGL の glReadPixels() のマニュアル http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/readpixels.html

taka-0910
質問者

お礼

回答していただきありがとうございます。 >念のために確認しますが,OpenGL ES じゃなくて OpenGL なんですか? はい、OpenGLです。 一度、RGBAフォーマットの方法で試してみます。

関連するQ&A

  • OpenGL 画像のα値操作

    こんにちは。 現在、授業の一環でGLUTを用いたOpenGLのプログラムを作っています。 そのプログラムの機能の中に、読み込んだ画像のα値を記憶した後、キー操作によって表示・非表示を切り替える機能を作ろうとしています。 目的の機能自体は一応途中まで(各ピクセルのα値を255⇔0への切り替え)は作れたのですが、原理がよく分かりません。 具体的に書くと、(幅)×(高さ)×(色のチャンネル数) の画像を読み込んだのに、4倍の高さの範囲までα値に関する処理を加えないと、処理後の効果が画像全体に現れないのです。 下にプログラムの断片を張るので、わかる方がいたら解説お願いします。 出来れば、後々のために理由を知っておきたいので。 -*-*-*-*-*-*-*-*-*- /* テクスチャの情報を格納する構造体 */ typedef struct{ unsigned int name; /* 識別番号 */ unsigned char* data; /* 画像のデータ */ int width; /* 画像の幅 */ int height; /* 画像の高さ */ int channels; /* 画像の色成分の数 */ }texture; /* テクスチャ(グローバル変数) */ texture a; /* 画面表示用の関数 */ void display (void) {  /* 初期化 */ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* 透明色を描けるようにする */ glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);  /* 描画 */ glDrawPixels(a.width, a.height, GL_RGBA, GL_UNSIGNED_BYTE, a.data); glutSwapBuffers (); } /* α値の操作(代入値がかわるだけなので、255にする方は省略) */ void alpham(void) { int i, j; for (i = 0; i < a.height * 4; ++i) { for (j = 0; j < (a.width); ++j) { a.data[(a.width * i) + (a.channels * j) +3] = 0; } } } ※画像データ の メモリ確保サイズ a.data = (unsigned char*) malloc(width * height * channels)

  • OpenGLでの描画のタイミング

     OpenGLの使い方について疑問があったので質問しました.  OpenGLを用いて3Dのゲームを作っています.しかし, どうも処理が遅くカクカクした動きになってしまいます. 描画の量が多くなるにつれて遅くなっているので,原因は 描画の時に原因があるようです.ダブルバッファリング を用いて描画しているのですが,描画のときは… 1「描画関数の実行」(glVertex3f()などの実行) 2「裏に描画」(見えていないバッファに描画) 3「裏表入れ替え」(2つのバッファを交換) 0「一定時間待機して自分自身を呼び出す」            (60FPSなら1/60秒程度) を繰り返すものと考えています.  「1230」と繰り返せば通常通り動くのですが, 「1」に計算がかかりすぎると,「2」と「3」が遅れてしまい, カクカクしてしまうのだろうと考えました. (↑これがそもそも間違っていたらすいません><)  そこで,対策を2つ考えたのですが,これでいいでしょうか? それとも,もっと良い方法はないでしょうか?(「1」を 速くするしか方法はないでしょうか?) 【1】一定時間待機する秒数を可変的にする  現在のところ,「0」では,1/60秒待機させています.  しかし,1に1/30秒かかったとすると,「1230」を 1回繰り返すのに,3/60秒かかってしまうことになり, 結局FPSは20止まりです.  そこで,「123」でかかった時間を記録し,その秒数 を1/60から引いた分だけ「0」で待機すれば,1/60秒になる だろう,という方法です. 【2】描画のタイミングを変える  現在のところ,「1230」の順番で繰り返しています. しかし,これでは描画の関数を呼び出した時,「1」に 1/30秒かかったとすると,実際に表示できるのは1/30秒後 ということになります.よって,プログラムの始めに 「1232」を実行しておき,描画の関数の中身は 「3120」とする,という方法です. (そもそも,「2」と「3」のタイミングを   離せるのかどうかもよくわかりません><)  もちろん【1】と【2】の方法は併用もできると思っています. 「2」はOpenGLに入っているglFlush() 「3」はOpenGLに入っているglutSwapBuffers() 「0」はOpenGLに入っているglutTimerFunc() を用いています. 質問が長くなってしまいましたが,よろしくお願いします. 参考までに… 【OS】Mac OS10.7(Lion) 【開発環境】Xcode3 【言語】c++ 【プログラミング歴】6年(c++2年,OpenGL1年) 【CPU】2.66 GHz Intel Core 2 Duo 【メモリ】4 GB 1067 MHz DDR3

  • OpenGLで描画するテクスチャのアルファ値(透明度)を変更したい

    初めて質問させていただきます、tri-oと申します。 現在OpenGLでの2D描画プログラムを書いています。 ある画像を描画する時、その画像全体のアルファ値に、任意の値を乗算して、全体の透明度を変更したいのですが、やり方がわかりません。 例えば、キャラクターが書いてある画像があって、時間が経つ毎に透明度が変わり、徐々に出現するようなプログラムを書きたいのです。 色々と検索してみたのですが、目的のページにたどり着けませんでした。 ご存知の方いらっしゃいましたら、ご回答よろしくお願いします。

  • openGLにおいて描画した物体によってできる影

    OpenGLで3次元オブジェクトを描画する際, 光源の位置によって物体の明るい場所と暗い場所を 表現する方法は知っています.(glShadeModel(GL_SMOOTH);など) しかし,このような方法ではオブジェクトにできる影は光源と オブジェクトの形状のみに依存し, その他のオブジェクトに影響されません. そこで,添付した画像のように, 「複数の3次元オブジェクトを描画した際に, 一方のオブジェクトがもう一方のオブジェクトによって影ができる」 という風に描画するにはどうすればよいですか? ご存知の方がいましたら,どうか教えていただけないでしょうか. よろしくお願いします.

  • カメラで撮影した画像をOpenGLで表示する方法

    webカメラで撮影した映像を,OpenGLを用いて表示することを考えております. 撮影した映像を,できる限り高速に表示する方法を教えていただけないでしょうか? 用途としては,仮想世界の視点移動に合わせて,カメラで撮影した画像を張り付けたポリゴンを 自由な視点から観察することを考えています. 私の考えつく解決策は,以下の通りです. 1.OpenGLの背景(バックバッファ)の領域を指定し,書き込む 2.ポリゴンにテクスチャマッピング 2.について実装してみたのですが,表示速度がいまひとつでした. 実装としては,テクスチャ用画像を,毎フレーム更新して, テクスチャマッピングする方法をとっています. コードを抜粋したものは,以下の通りです. ------------------------------------ glBindTexture(GL_TEXTURE_2D, g_texture[0]);//テクスチャの指定 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); gluBuild2DMipmaps(GL_TEXTURE_2D, 3, texture_img[0]->width,texture_img[0]->height, GL_RGB,GL_UNSIGNED_BYTE,texture_img[0]->imageData); ---------------------------------- ※texture_img[0]を毎フレーム更新して,テクスチャマッピング お忙しいと思いますが, アドバイスをいただけますと幸いです. よろしくお願いいたします.

  • OpenGLでのオブジェクトの描画上限

    OpenGLを使って、オブジェクトを描画する場合の上限はあるのでしょうか。 下記のようにリストを使ってオブジェクトを501個以上描画するとうまく描かれませんでした。 GLUquadricObj *sphere; //オブジェクトポインタを準備 GLint list; /* 新しいリスト番号を取得 */ list=glGenLists(1); /* 新しいリストを作成 */ glNewList(list, GL_COMPILE); /* 球を描画 */ for(i=0;i<600;i++){ //オブジェクトを生成 sphere = gluNewQuadric(); //球を描画 半径1.0,緯経それぞれ20.0分割 gluSphere(sphere, 2.0, 20.0, 20.0); } /* リスト作成終了 */ glEndList(); 仕様なのかPCのスペックの問題なのかわかりましたらアドバイスお願い致します。

  • vc++のpictureboxにopenGLの画像を描画する方法につい

    vc++のpictureboxにopenGLの画像を描画する方法について。 現在、Visual C++ 2010のフォームアプリケーションで、任意のパラメータを入力したらその値に応じて物体の動きが変わるといったアプリケーションを開発しています。その動き方をopenGLでアニメーションとして可視化したいと思っています。そして、そのアニメーションをvc++のフォームアプリケーションのpictureboxに表示したいと思っているのですが、vc++とopenGLのどちらもかなりの初心者なので、pictureboxへの表示の仕方がわかりません。 以下に参考URLを貼らせていただきます。このようなものにパラメータを入力する部分を設けたものを作りたいのですが、まったく意味がわかりません。どなたかご教授お願いいたします。 http://www.t-pot.com/program/127_OpenGLNET/index.html

  • カラー画像からグレースケール画像フォーマットの変換

    カラー画像からグレースケール画像フォーマットの変換するプログラムなんですが、いまいち理解できていません。 プログラムはRGB構造体を使ってのものなんですが添削お願いいたします。 #include<stdio.h> #include<stdlib.h> typedef struct _RGB { unsigned char r; unsigned char g; unsigned char b; } RGB; int main(int argc, char *argv[]) { int x, y; unsigned char *in, *out; int i, j, Magic, level; unsigned char tmp[255]; RGB **pixels; int width = 255; int height = 255; int size = width * height; FILE *fin, *fout; if(argc != 3){ printf("Usage : %s input outpu \n", argv[0]); exit(1); } fin = fopen(argv[1], "rb"); fgets(tmp, 255, fin); if(tmp[0] != 'P'){ return 0; } sscanf(tmp, "P%d", &Magic); if(Magic < 1 || Magic > 6){ return 0; } do{ fgets(tmp, 255, fin); } while(tmp[0] == '#'); sscanf(tmp, "%d %d", &x, &y); if(x < 1 || y < 1){ return 0; } fgets(tmp, 255, fin); sscanf(tmp, "%d", &level); printf("P%d\n", &Magic); printf("%d %d\n", x, y); printf("%d\n", level); in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in, sizeof(unsigned char), x*y, fin); pixels = (RGB**)malloc(width*sizeof(RGB*)); pixels[0] = (RGB* )malloc(size * sizeof(RGB)); for(i = 1; i < width; i++){ pixels[i] = pixels[i - 1] + height; } free(pixels[0]); for(i = 1; i < width * height * 3; i++){ out[i] = pixels[i][0].r * 0.299 + pixels[i][1].g * 0.587 + pixels[i][2].b * 0.114; } fout = fopen(argv[2], "wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); free(pixels); free(in); free(out); free(fin); free(fout); }

  • 画像のRGBの値

    画像フィルタが必要になり、そのために画像の性質を知るために、画像のRGBの値を直接求めようと思いました。 具体的には、画像ファイル(BMP)があり、その画像の全画素のRGBの値をテキストファイル(CSV形式)に変換したいのです。そのようなツールありますか? 特殊な用途なので、 while(getpixel(r,g,b)) { printf("%d,%d,%d\n",*r,*g,*b); } のようなプログラムを書かないといけないと思うのですが、「BMPファイルの先頭から順番に画素のRGBの値を持ってくる関数getpixel」が書けません。

  • 16ビットグレースケールの画像を描画させたい。

    16ビットグレースケールの画像を描画させたい。 こんにちは。 Photoshopで16ビットグレースケールのPNGファイルを作り、 それをlibpngを使って読み込むプログラムを書きました。 16ビットRGBではなくグレースケールです。1ピクセルの 情報は0~65535です。 640*480の画像で例えるならば、640*480*2の大きさで CreateDIBSection関数を使って作成しているだけなので Bitblt関数を使って描画させようとしても、16ビットRGB として描画しようとするので正しく表示されません。 これを正しく描画させる方法はありませんでょうか? さらにLineToやRectangle等で編集もしたいのですが、 可能でしょうか?