プロが教えるわが家の防犯対策術!

画像のRGB値をExcelにエクスポートしたいのですが…、どなたか教えていただけませんか?

A 回答 (9件)

>CSV形式のデータを使うだけなら、C等でツールを作ればデータとしては、作れますが...。


取りあえず、簡単に作ってみましたので、以下に貼ってみます。(一応、BCCで動作は確認しました。)
------------------------------
/*BMP to CSV Convert*/
/*Present from Quenista*/
/*2001/12/14-2001/12/14*/

#defineVERSION(1.00)
#defineHELP_STRINGS"BMP2CSV _InputFile_ [_OutoutFile_]\n"

#include<dos.h>
#include<conio.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<stdarg.h>

/*BMP Data Format*/
typedefstructBmpFileHeader{
unsignedcharszType[2];/*'BM' Strings*/
unsignedlongulSize;/*Hedder+Infomation+Pallet+Data Size*/
unsignedshortusReserved1;/*Reserved*/
unsignedshortusReserved2;/*Reserved*/
unsignedlongulOffBits;/*Hedder+Infomation+Pallet Size*/
}BMHD;

typedefstructBmpInfomation{
unsignedlongulSize;/*Infomation Data Size*/
unsignedlongulWidth;/*X Pixel Size*/
unsignedlongulHeight;/*Y Pixel Size*/
unsignedshortusPlanes;
unsignedshortusBitCount;/*1Pixel Bits Size*/
unsignedlongulCompression;
unsignedlongulSizeImage;/*Data Byte Size*/
unsignedlongulXPelsPerMeter;/*X Pixel/Meter*/
unsignedlongulYPelsPerMeter;/*Y Pixel/Meter*/
unsignedlongulClrUsed;
unsignedlongulClrImportant;
}BMIF;

typedefstructPalletInfomation{
unsignedcharucB;
unsignedcharucG;
unsignedcharucR;
unsignedcharucC;
}PLIF;

voiderror_exit(char*str,...)
{
intiError;

iError=(errno==(int)NULL)?-1:errno;
fputc('\n',stderr);
fprintf(stderr,str);
fputc('\n',stderr);
fcloseall();
exit(iError);
}

intbmp_csv(FILE*fpOutput,FILE*fpInput)
{
intiLoop;
intiLoopX,iLoopY,iPallet;
unsignedlongulBmpDataStack;
BMHDbmhdBmpHedder;
BMIFbmifBmpInfomation;
PLIFplifBmpPallet[256];
PLIFplifPallet;

/*Get BMP Headder*/
fread((void*)&bmhdBmpHedder,sizeof(BMHD),1,fpInput);
if(strncmp(bmhdBmpHedder.szType,"BM",2)!=0)error_exit("Bmp Data Error!");
fread((void*)&bmifBmpInfomation,sizeof(BMIF),1,fpInput);

/*Get BMP Pallet*/
for(iLoop=0;iLoop<(int)((bmhdBmpHedder.ulOffBits-(sizeof(BMHD)+sizeof(BMIF)))/4);iLoop++){
fread((void*)&plifBmpPallet[iLoop],sizeof(PLIF),1,fpInput);
}

/*Make CSV Hedder*/
for(iLoop=0;iLoop<(int)bmifBmpInfomation.ulWidth;iLoop++){fprintf(fpOutput,"B,G,R,");}
fprintf(fpOutput,"\n");

/*Get Map Data*/
for(iLoopY=0;iLoopY<(int)bmifBmpInfomation.ulHeight;iLoopY++){
for(iLoopX=0;iLoopX<(int)bmifBmpInfomation.ulWidth;iLoopX++){
if((iLoopX%(8/bmifBmpInfomation.usBitCount))==0){
fread((char*)&ulBmpDataStack,((bmifBmpInfomation.usBitCount+7)/8),1,fpInput);
}
if(bmifBmpInfomation.usBitCount<=8){
iPallet=(unsignedchar)(ulBmpDataStack&(~(0xFF>>bmifBmpInfomation.usBitCount)))>>(8-bmifBmpInfomation.usBitCount);
plifPallet.ucB=plifBmpPallet[iPallet].ucB;
plifPallet.ucR=plifBmpPallet[iPallet].ucR;
plifPallet.ucG=plifBmpPallet[iPallet].ucG;
ulBmpDataStack<<=bmifBmpInfomation.usBitCount;
}
else{
plifPallet.ucB=(unsignedchar)(ulBmpDataStack&(~(0xFF<<(bmifBmpInfomation.usBitCount/3))));
ulBmpDataStack>>=((bmifBmpInfomation.usBitCount/3)-1);
plifPallet.ucR=(unsignedchar)(ulBmpDataStack&(~(0xFF<<(bmifBmpInfomation.usBitCount/3))));
ulBmpDataStack>>=((bmifBmpInfomation.usBitCount/3)-1);
plifPallet.ucG=(unsignedchar)(ulBmpDataStack&(~(0xFF<<(bmifBmpInfomation.usBitCount/3))));
ulBmpDataStack>>=((bmifBmpInfomation.usBitCount/3)-1);
}
fprintf(fpOutput,"%03d,%03d,%03d,",plifPallet.ucB,plifPallet.ucR,plifPallet.ucG);
}
fprintf(fpOutput,"\n");
}

fclose(fpInput);
fclose(fpOutput);

return0;
}

voidmain(unsignedintargc,unsignedchar*args[])
{
FILE*fpInput;
FILE*fpOutput;
unsignedintuiCount;

printf("BMP to CSV Convert Tool Version %.2f Copyright(c) Quenista\n",VERSION);

/*Initial*/
uiCount=1;

if(argc<2)error_exit(HELP_STRINGS);

while(args[uiCount][0]=='-'){
switch(args[uiCount][1]){
default:
error_exit(HELP_STRINGS);
break;
}
uiCount++;
}

if((fpInput=fopen(args[uiCount],"rb"))==NULL)error_exit("Input File Open Error!");
uiCount++;
if(argc>uiCount){
if((fpOutput=fopen(args[uiCount],"w+b"))==NULL)error_exit("Output File Open Error!");
}
else{
fpOutput=stdout;
}
if(bmp_csv(fpOutput,fpInput)!=0)error_exit("Abnormal End!");

fcloseall();

printf("Convert End!\n");
}

------------------------------
取りあえず、普通のコンパイラなら通ると思いますが、コンパイル時オプションにバイトのAlignだけ注意が必要です。
    • good
    • 0

取りあえず、1つづつ補足します。


>1Cellに数個づつ入れるとか、数行に分ける等の対処が必要そうです...。

例えば、数行に分ける方法ですが、
Cells(j + 1, i + 1) = rr
とセルに値を入れている行で、
Cells(J*int(Bmp.biWidth/256)+1,(i mod 256)+1) = rr
と言う様にすると、256で折り返すと思います。(青(bb)と緑(gg)も同様に。)
    • good
    • 0
この回答へのお礼

quenistaさん、いつも私のわがままを聞いて下さって有難うございます。
感謝の気持ちでいっぱいです。
まだまだ、駆け出し中の初心者ですが頑張って行こうと思います。

お礼日時:2001/12/14 02:02

アドバイスが、遅くなってすいません。



Getの可変長取得方式は以下の書式の様です。
VarString = buf((Bmp.biWidth*3-1)," ")
Get #1,,buf

ヘルプのGetのBinaryの所に書いてありましたので、一度試して見られると良いかも知れません。

>Excelの列サイズが256行までみたいでそれを超える画像を扱うとエラーが出ちゃいます。
成る程、これはExcelの制限みたいですね。
確かに、そのままでは無理そうな感じです。
1Cellに数個づつ入れるとか、数行に分ける等の対処が必要そうです...。

このデータを、何に使われるのでしょうか?
CSV形式のデータを使うだけなら、C等でツールを作ればデータとしては、作れますが...。

この回答への補足

quenistaさん、返事&お礼が遅くなってごめんなさい。
いろいろな情報有難うございます。
とりあえず、Excelで処理したいので、サイズ固定でやってみようと思っています。
Cとかを勉強してる時間がないので…。
ですが、もしよかったら参考までに
>1Cellに数個づつ入れるとか、数行に分ける等の対処が必要そうです...。

>CSV形式のデータを使うだけなら、C等でツールを作ればデータとしては、作れますが...。
について少しアドバイスをいただけたらと思っています。

補足日時:2001/12/13 23:47
    • good
    • 0

>その次のデータサイズ指定で読み込む方法がわかりません。


Get #1, , buf 'One Line Reading...
の所で、
Get #1,(Bmp.biWidth*3-1),buf
の様な感じで、サイズ指定出来ると思うのですが...。

問題は、このサイズを指定する場所を覚えてないんです。
(この辺は、ヘルプ等で”Get”を調べて頂ければ良いのですが...。)

私のPCは、再インストール中で未だExeclが入ってないので、確認する事が出来ないのです。(こちらで試す環境があれば、直ぐなんですけどね。)

>For文のところは可変長の対応が出来てるということは
>Bmp.biWidth-1 と Bmp.biHeight-1
>はいじらなくてもいいということでしょうか?
ええ。
この二つはこのままで良さそうですよ。

もう少しだと思います。
頑張ってみましょう!

どうして駄目だった場合は、
Xサイズを固定にしてしまえば、取りあえずは使えますね。
これは、先程のBufの値を変えるだけで対応出来ますね。

この回答への補足

quenistaさん、問題発生です!!
サイズ指定の場所もわからないし、時間も無いしでとりあえずXサイズ固定でやってみたんですけど…
Excelの列サイズが256行までみたいでそれを超える画像を扱うとエラーが出ちゃいます。
これが限界なのでしょうか?それならそれでしかたないのですが…。

補足日時:2001/12/13 11:21
    • good
    • 0

>Static buf(383 * 3) As Byte


では無く、元の数値の383が、128*3の値です。
つまり、Xサイズが128固定なので、この数値になって居ますが、今回は可変にしたいと言う事ですので、使用するXサイズの最大値*3の値を入れると言う事に成ります。
例えば、MAXを640とするなら、
Static buf(1919) As Byte
と記述すれば良いと思います。

先ず、このプログラム中のBmp.biWidthがXサイズ,Bmp.biHeightがYのサイズですね。

>>Getの時に、Bmp.biWidth*3の長さで読み出す様にする。のところは
>For i = 0 To Bmp.biWidth * 3 - 1
>でいいのでしょうか?
先程のBufの設定で、Bufの確保は出来てますので、
今度は、読み込む所を直してやる必要があります。
つまり、
Get #1, , buf 'One Line Reading...
の行で、データサイズ指定で読み込めば良いのです。
(引数の場所等は、ちと手元に資料が無いので、調べて見て下さいね。)

その時のデータサイズが、(Bmp.biWidth*3-1) の値を指定すれば良いのです。

For文のところは、元々Bmp.biWidthでデータを取得してますので、可変長の対応が出来てると思って良いです。

>>このプログラムでは、パレットデータには対応してないので、24BitフルカラーのBMPに変換して置いてから、使う必要が有りますね。
>>(確かに、パレット対応すると手間ですからね。)
>のところを少し詳しく教えてください。
一言で、BMP形式と言っても、幾つかの種類が有ります。
例えば、モノクロ2階調やモノクロ256階調,カラー256色,フルカラー等です。
その中で、このプログラムはフルカラーにのみ対応している様です。

フルカラー以外は、
>If Bmp.biBitCount <> 24 Then 'Full Color Image?
ではじかれる様になってます。

>それから、Global Data(128, 128)の宣言はこのプログラム(テキストから抜粋)に続きがあるのでそこで使われるのだと思います…。
サイズ制限を可変長にする為には、ここの値を使ってるのであれば、修正してやる必要が有りそうな感じ(以後のプログラッムが解らないので、何とも言えませんが。)です。
全く、使用してないなら、削除しても問題無いと思いますよ。

>ばかばかしい質問でしょうがどうか宜しくお願いします。
いえいえ。
ちゃんとやり取りをして頂けるので、こちらもアドバイスしてて楽しいです。(^_^)

かなり余談ですが...。
次に回答出来るは、11時以降になると思います。(もし、待っておられると悪いので...。)

この回答への補足

quenistaさん、いままでねばったのですが、どうしてもうまくいきません…。
申し訳ありませんが、もう少し教えてください。
quenistaさんの前回の回答に習って、Bufの確保まではわかったのですが、
その次のデータサイズ指定で読み込む方法がわかりません。
For文のところは可変長の対応が出来てるということは
Bmp.biWidth-1

Bmp.biHeight-1
はいじらなくてもいいということでしょうか?

補足日時:2001/12/12 23:03
    • good
    • 0

動かして見た訳ではないで、確実では無いですが、



先ず、以下の点を改修する必要が有りそうですね。
・Bufの容量を増やす。(Xサイズ*3)
・Getの時に、Bmp.biWidth*3の長さで読み出す様にする。
ですかね。

後、Global Data(128, 128)の宣言がありますが、何処で使ってます?

このプログラムでは、パレットデータには対応してないので、24BitフルカラーのBMPに変換して置いてから、使う必要が有りますね。
(確かに、パレット対応すると手間ですからね。)

この回答への補足

quenistaさん、すみませんがもう少し詳しく教えてください…

>Bufの容量を増やす。(Xサイズ*3)のところは

Static buf(383 * 3) As Byte

でいいのでしょうか?

>Getの時に、Bmp.biWidth*3の長さで読み出す様にする。のところは

For i = 0 To Bmp.biWidth * 3 - 1

でいいのでしょうか?

あと、

>このプログラムでは、パレットデータには対応してないので、24BitフルカラーのBMPに変換して置いてから、使う必要が有りますね。
(確かに、パレット対応すると手間ですからね。)

のところを少し詳しく教えてください。

それから、Global Data(128, 128)の宣言はこのプログラム(テキストから抜粋)に続きがあるのでそこで使われるのだと思います…。

ばかばかしい質問でしょうがどうか宜しくお願いします。

補足日時:2001/12/12 17:49
    • good
    • 0

モジュール等が有るか解らないのですが、


もしBMPから展開するのではあれば、以下にヘッダー部の情報を書いときます。
(C形式で、見難いかも知れませんが...。)

BMP ヘッダー部
typedefstructBmpFileHeader{
unsignedcharszType[2];/*"BM"固定*/
unsignedlongulSize;
/*未使用*/unsignedshortusReserved1;
/*未使用*/unsignedshortusReserved2;
unsignedlongulOffBits;
};

typedefstructBmpInfomation{
unsignedlongulSize;
unsignedlongulWidth;
unsignedlongulHeight;
/*未使用*/unsignedshortusPlanes;
unsignedshortusBitCount;
/*未使用*/unsignedlongulCompression;
unsignedlongulSizeImage;
/*未使用*/unsignedlongulXPelsPerMeter;
/*未使用*/unsignedlongulYPelsPerMeter;
/*未使用*/unsignedlongulClrUsed;
/*未使用*/unsignedlongulClrImportant;
};

パレットのデータ
typedefstructPalletInfomation{
unsignedcharucB;
unsignedcharucG;
unsignedcharucR;
unsignedcharucX;
};

上記が、BMP Fileのヘッダー部のデータです。
/*未使用*/の項は、今回は使わなくて良いと思います。

これ、解ります?
この辺が解らないなら、かなり手間が掛かるかも知れません。

Cのコンパイラを使えるなら、BMP→CSVのツールをCで簡単に書いてみましょうか?(汚いかも知れませんが...。(苦笑))
ココに書ききれるかどうかの問題も有りますが...。
(VBAは、手間が掛かるので...。)

この回答への補足

quenistaさん、度々の回答有難うございます。
私の方もいろいろな文献で勉強したところ、ExcelのVBAで読み込む方法を見つけました。
ですが、これは128×128ピクセルサイズまでしか読み込めないようです。
扱いたい画像サイズはもう少し大きいもの(300×300くらい)で画像によってことなります。
このような任意の大きさの画像ファイルを扱うにはどうすれば良いのでしょうか?
ちなみにプログラムの内容は以下のようなものです。

”ビットマップ構造体の宣言”
Type Bitmap
'bfType As String * 2
'bfType(1) As Byte 'BM
bfType As Integer '42 4D (BM)
bfSize As Long
bfReserved1 As Integer '0
bfReserved2 As Integer '0
bfOffBits As Long
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer '1
biBitCount As Integer
biCompression As Long '1
biSizeimage As Long
biXPlanePerMeter As Long
biYPlanePerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type

”ビットマップを読み込むサブプロシージャ”
Sub DIBFullColorView(fname As String)
'DIB Loading...
'Image Size 128Pixel*128Pixel*24bit DIB Format File Loading

Dim j As Integer
Dim i As Integer
Dim rr, gg, bb As Integer
Static buf(383) As Byte
Static Bmp As Bitmap

Close #1
Open fname For Binary As #1 'FileOpen
Get #1, , Bmp 'BitmapHeader Reading...

If Bmp.biBitCount <> 24 Then 'Full Color Image?
Close #1
Exit Sub
End If

'ImageData Loading...
For j = 0 To Bmp.biHeight - 1 'y-axes loop
If ((j Mod 50) = 0) Then Beep 'MsgBox (j & "line")
Get #1, , buf 'One Line Reading...
For i = 0 To Bmp.biWidth - 1 '256Gradition data creating...
' ::x-axes loop
rr = AscB(MidB$(buf, i * 3 + 2 + 1, 1)) 'Get String 1 Byte
Worksheets("R").Activate
Cells(j + 1, i + 1) = rr
gg = AscB(MidB$(buf, i * 3 + 1 + 1, 1)) 'Get String 1 Byte
Worksheets("G").Activate
Cells(j + 1, i + 1) = gg
bb = AscB(MidB$(buf, i * 3 + 0 + 1, 1)) 'Get String 1 Byte
Worksheets("B").Activate
Cells(j + 1, i + 1) = bb
Next i
Next j
Close #1
End Sub

”メインのプロシージャ”
Global Data(128, 128) As Integer

Sub main()
Dim Title, MyValue As String
Title = "InputBox"
Msg = "Filename"
MyValue = InputBox(Msg, Title, "dmy.bmp")
MsgBox (MyValue)
DIBFullColorView (MyValue)
' DIBFullColorView2GRAY (MyValue)
' DIBFullColorSave (MyValue)

End Sub

補足日時:2001/12/12 15:55
    • good
    • 0

>Excel VBAでもこのような処理が出来るようなことを聞いたのですが…、


確かに、VBAで出来るとは思いますよ。

画像形式をBMPとして、考えますと。(一番簡単なので。)

プログラムの経験が有るのであれば、BMPから画像を取り出しながら、単純にセルに書き込めば良いのです。
BMPのヘッダー部が読めたら、そんなには難しく無いとは思います。

もし、解らない事が御座いましたら、補足致しますよ。

>Vector等で転がってるかも知れませんね。
ザクッと見た感じでは、無さそうでした。

この回答への補足

quenistaさん、有難うございました。
初心者ですが少し自分で勉強しながらやってみようと思います。

補足日時:2001/12/12 12:27
    • good
    • 0

どの様な意味でしょうか?



画像を展開して、1ドットを3セルに表現するのですか?
或いは、1ドットを1セルの色とするのでしょうか?

ただ、どちらもBmpから展開するとしても、簡単なプログラムが必要ですね。
もしかしたら、Vector等で転がってるかも知れませんね。

少し、意図が解らなかったので...。

後、WindowsとExcelのバージョンと画像の形式も表記された方が良いと思いますよ。

この回答への補足

quenistaさん、ご指摘有難うございました。ならびに説明不足ですみません。
補足いたします…
画像解析をするためにBitmapファイルのカラー画像のRGB値を画素毎に読取って、
それぞれの値をExcelのそれぞれのセルに入れたいのです。
ちなみにWindowsとExcelバージョンはWindows98とExcel2000です。
以前、Excel VBAでもこのような処理が出来るようなことを聞いたのですが…、
詳しいことがわかりません。
VC++6.0とVB6.0での方法でもかまいません、なるべく簡単な方法はないのでしょうか?

補足日時:2001/12/12 01:34
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!