C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: pictureBoxへのraw画像の表示


(過去ログ 112 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■66626 / inTopicNo.1)  pictureBoxへのraw画像の表示
  
□投稿者/ パブロフの犬 (1回)-(2013/05/12(Sun) 15:33:16)

分類:[C#] 

Microsoft Visual Studio 2012
C#

画像処理を行うために、C#を勉強中のものです。画像表示について質問です。

OpenDialogで選択したraw画像をpictureBoxに表示する方法を教えて下さい。
raw画像は512*512の2バイトのraw画像で、little endian形式です。

以下、途中までのコード

private void openRawButton_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() != DialogResult.OK) return;

short []image;
int width, height;

width = height = 512;
image = new short [width * height];

//画像ファイルの読み込み
BinaryReader fp = new BinaryReader(File.Open(openFileDialog1.FileName, FileMode.Open));

for (int i = 0; i < width * height; i++) image[i] = fp.ReadInt16();

fp.Close();


//読み込んだ画像ファイルが格納してあるimageを表示する




}


画像ファイルの読み込みまではできていると思うのですが、それ以降がわかりません。
Bitmapを使うといいのでしょうが、どう書いていいのか分からないので、教えてください。
引用返信 編集キー/
■66627 / inTopicNo.2)  Re[1]: pictureBoxへのraw画像の表示
□投稿者/ Azulean (159回)-(2013/05/12(Sun) 16:04:20)
16bit/pixel のデータのようですが、どのように表示したいのでしょうか。
単に 8bit 右にシフトしたデータをグレースケールで表示したいのか、特定の範囲を取り出して 0 〜 255 に拡大したいのか、そのあたりの方針は決まっていますか?

それによって演算した結果を元に Bitmap を LockBits して得られる BitmapData に書き込み(Scan0 に Marshal.Copy か unsafe コードでポインタ操作)することになるでしょう。
引用返信 編集キー/
■66628 / inTopicNo.3)  Re[2]: pictureBoxへのraw画像の表示
□投稿者/ パブロフの犬 (2回)-(2013/05/12(Sun) 16:15:13)
Azulean さん

 返信ありがとうございます。
記入していませんでしたが、前者の8bitシフトしたデータをグレースケール表示したいです。
よろしくお願いします。
引用返信 編集キー/
■66629 / inTopicNo.4)  Re[3]: pictureBoxへのraw画像の表示
□投稿者/ Azulean (160回)-(2013/05/12(Sun) 17:40:19)
戦略としては二つ考えられます。(実際にコードを書いていないのでその後にトラブルがあるかは未確認です)
一方は、PixelFormat.Format8bppIndexed というフォーマットにしてカラーパレットに色を入れることで、8bits/pixel でデータを作る方法です。
他方は、PixelFormat.Format24bppRgb などとして R = G = B となるようにデータを入れることで見た目をグレースケールにしてデータを作る方法です。
どちらが好ましいかはその後の使い方によると思うので、考えてみてください。

さて、「したいです」とだけしかご返答されていませんが、調べてもまったくわからなかったか、調べていないかのどちらなのでしょうか。

LockBits のページを見ると、一例としてすべての画素を赤っぽくするサンプルが掲載されています。
http://msdn.microsoft.com/ja-jp/library/5ey6h79d.aspx

ここを参考に、画素ごとに計算した 8bit の値を入れれば PixelFormat.Format24bppRgb を選択した場合はうまくいくかと思います。(R=G=B となるように 3 個とも同じ値を入れる)
PixelFormat.Format8bppIndexed の場合は、カラーパレットを入れておく必要があります。このあたりは私自身でさっと書けるほど身についていないので、一度調べてみてください。
引用返信 編集キー/
■66630 / inTopicNo.5)  Re[4]: pictureBoxへのraw画像の表示
□投稿者/ パブロフの犬 (3回)-(2013/05/12(Sun) 20:14:32)
返信ありがとうございます。もちろん、事前に調べていますが、わからなかったのでここに質問させてもらってます。

PixelFormatは24bitにして、R=G=Bとするつもりです。
サンプルではよくわかりませんでした。今回はshort型の配列(コードではimageという配列)をBitmapに登録するというところがサンプルとは異なるので、わかりませんでした。
どなたか、わかる方いらっしゃたら、返信ください。

ちなみに、borlandのc++ builderを経験しており、その移行をしたいと思い投稿しました。
c++ builderのコードを下に書いています。



int fp;
width = height = 512;

short *image = new short [width*height];

if(OpenDialog1->Execute() != true) return;

//画像ファイルの読み込み
fp = FileOpen(OpenDialog1->FileName, fmOpenRead);
if (fp < 0) return;
FileRead(fp, image, width*height*sizeof(short));
FileClose(fp);


//読み込んだ画像ファイルが格納してあるimageを表示する
pBitmap = new Graphics::TBitmap();
pBitmap->PixelFormat = pf24bit;
pBitmap->Width = width;
pBitmap->Height = height;

Byte* Ptr;
for (int j=0; j< pBitmap->Height; j++) {
Ptr = (Byte*)pBitmap->ScanLine[j];

for (int i=0 ; i< pBitmap->Width ; i++) {
Ptr[3*i]= Ptr[3*i+1]= Ptr[3*i+2] = image[j*pBitmap->Width+i] >> (10 - 8);
}
}

Image1->Picture->Assign(pBitmap);

引用返信 編集キー/
■66631 / inTopicNo.6)  Re[5]: pictureBoxへのraw画像の表示
□投稿者/ Azulean (161回)-(2013/05/12(Sun) 20:23:15)
2013/05/12(Sun) 20:28:43 編集(投稿者)

No66630 (パブロフの犬 さん) に返信
> 返信ありがとうございます。もちろん、事前に調べていますが、わからなかったのでここに質問させてもらってます。

そうであれば、そのことを明確にしてください。
それを省略することによって、「丸投げ?」と思われ、心証を悪くすることにつながります。


> PixelFormatは24bitにして、R=G=Bとするつもりです。
> サンプルではよくわかりませんでした。
> 今回はshort型の配列(コードではimageという配列)をBitmapに登録するというところがサンプルとは異なるので、わかりませんでした。

違う部分とは、「short 型を byte 型に変換する必要があること」と、「R = G = B として 1 ピクセルあたりのデータ量を水増しする必要があること」ですよね。
「異なるのでわかりません」と書くのはかんたんですが、どの部分を当てはめるのが難しい、わからないとお考えでしょうか?


> ちなみに、borlandのc++ builderを経験しており、その移行をしたいと思い投稿しました。
> c++ builderのコードを下に書いています。

このコードを自力で書けるのなら、もう書けるんじゃないかなと思えてしまいます。
どの部分がイメージつかないのでしょうか。
(経験がある、コードを書いたという断片から、自力で書いたように見えるため、このような書き方をしています)

> Byte* Ptr;
> for (int j=0; j< pBitmap->Height; j++) {
> Ptr = (Byte*)pBitmap->ScanLine[j];
>
> for (int i=0 ; i< pBitmap->Width ; i++) {
> Ptr[3*i]= Ptr[3*i+1]= Ptr[3*i+2] = image[j*pBitmap->Width+i] >> (10 - 8);
> }
> }

要するにこのブロックに相当することを、BitmapData.Scan0 に対して実現してあげればよいだけです。
ところで、先ほどあなたは「右に 8 ビットシフトする」趣旨の発言をされていますが、上記のコードは違います。きちんとその点を踏まえた発言であればよいのですが…。


// ttp://wp.me/p19AcI-5V
引用返信 編集キー/
■66661 / inTopicNo.7)  Re[6]: pictureBoxへのraw画像の表示
□投稿者/ パブロフの犬 (4回)-(2013/05/13(Mon) 22:11:46)
Azulean さん

 C#初心者の私にここまで教えていただきありがとうございます。
サイトのサンプルをかなり参考にさせていただきましたが、ようやく画像表示のプログラムができました。
C#移行の第一歩ですので、今後もご教授いただくかもしれません。

完成したプログラムのコードを下に書いておきます。
また、扱うraw画像は2Byteといっていましたが、もっと詳細にいうと10bitの画像でした。
ゆえに2bitシフトでプログラムは書いています。

C#特有のメソッドがまだ詳しくわかっていませんが、これから勉強していきます。
LockBits、stride、scan0、UnlockBitsなど。
C++ buildeになかったものは、やはり勉強しないと厳しいですねー。。


private void openRawButton_Click(object sender, EventArgs e)
{
if (openFileDialog1.ShowDialog() != DialogResult.OK) return;

short []image;
int width, height;

width = height = 512;

image = new short [width * height];

//画像ファイルの読み込み
BinaryReader fp = new BinaryReader(File.Open(openFileDialog1.FileName, FileMode.Open));

for (int i = 0; i < width * height; i++) image[i] = fp.ReadInt16();

fp.Close();


//Bitmapに画像を登録し、表示する
Bitmap img = new Bitmap(width, height, PixelFormat.Format24bppRgb);

BitmapData imgData = img.LockBits(
new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.WriteOnly,
PixelFormat.Format24bppRgb);

IntPtr currentPointer = imgData.Scan0;

int stride = imgData.Stride;

byte[] oneLineData = new byte[width * 3];
for (int y = 0; y < height; ++y)
{
for (int x = 0; x < width; ++x)
{
// 3bytes per pixel
byte value = (byte)(image[width * y + x] >> 2);
oneLineData[x * 3] = value;
oneLineData[x * 3 + 1] = value;
oneLineData[x * 3 + 2] = value;
}
Marshal.Copy(oneLineData, 0, currentPointer, width * 3);
currentPointer += stride;
}

img.UnlockBits(imgData);

pictureBox1.Image = img;
}
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -