- ベストアンサー
MFCでのBITMAP作成について
- VC++2005MFCで開発しています。カメラからの画像入力の部分を作成しているのですがchar配列からのカラーbitmapの作成の仕方が分かる方いませんでしょうか?
- 直接ファイルに書き込む方法ですとフォーマット通りに書き込めば良いとは思うのですが、画面表示をしたいのでCBitmap又はHBitmapで取得したいです。
- 調べていると、モノクロだとSepBitmapBitsでできそうです。しかし、msdnを見るとカラーの場合はSetDIBitsを使用しろとあるのですが、SetDIBitsの項を見ると何か思っている用法と違いそうです。また、VC++.NETですとDrawing::Bitmap(( width, height, stride, format, scan0);でフォーマットを指定して作成できそうなのですが、それに相応するようなものはないかと探しているのですが見つかりません。すいませんがご教授お願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
回答2;続きです。 これは、画像ファイルに下に、 新しく勝手に作成したデータを追加して全体を一つの画像ファイルにしています。 勝手に追加しているデータ部分をカメラからの画像データにしてテストすれば 見えるようになると思います。 参考になれば幸いです。VC++2005を使っています。 if((dstfile = fopen(ct, "wb")) == NULL){ printf("Can not open crypted file. \n"); return; } srand( (unsigned)time(NULL) ); //in constracter strcpy(FName, pt);// = srcfile.GetFileName(); nsize = strlen(FName); //.GetLength();// length of file name. // 平文 fseek(srcfile, 0, SEEK_END); long filelen = ftell(srcfile); fseek(srcfile,0,0); fsize = filelen; //fsize = srcfile.GetLength();// as char 8 bit sidesize = int((4+1+(fsize/2)+1+(nsize/2))/nhsize) + 1; //sidesize = 1 + (int)sqrt((double)(4+1+(fsize/2)+1+(nsize/2)));// as short int 16 bit // Write the header of bitmap file. *((DWORD*)(&(bmpHeader[2]))) = 54+4*sidesize*(sidesize + nvsize); *((DWORD*)(&(bmpHeader[18]))) = nhsize; *((DWORD*)(&(bmpHeader[22]))) = sidesize + nvsize; *((DWORD*)(&(bmpHeader[34]))) = sidesize*(sidesize + nvsize); fwrite( bmpHeader,sizeof(char),54, dstfile); //dstfile.Write(bmpHeader, 54); j = rand(); // 16 bits k = nsize & 0x0000ffff; jj = (j<<16) + (j^k); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit j = rand(); // 16 bits k = nsize & 0xffff0000; jj = (j<<16) + (j^(k>>16)); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit j = rand(); // 16 bits k = fsize & 0x0000ffff; jj = (j<<16) + (j^k); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit j = rand(); // 16 bits k = fsize & 0xffff0000; jj = (j<<16) + (j^(k>>16)); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit for(i=0; i<nsize/2 ; i++){ j = rand(); // 16 bits k = (unsigned char)FName[2*i]; l = (unsigned char)FName[2*i+1]; jj = (j<<16) + (j^((k<<8)+ l)); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit } if(nsize%2 == 1){ j = rand(); // 16 bits k = (unsigned char)FName[nsize-1]; jj = (j<<16) + (j^((k<<8)+ 0)); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit } if(nsize%2 == 0){ j = rand(); // 16 bits k = 0; jj = (j<<16) + (j^((k<<8)+ 0)); *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit } for(i=4+1+nsize/2; i<sidesize*nhsize ; i++){ j = rand(); // 16 bits if(1 == fread(tmprbuf, sizeof(char), 1, srcfile)){//1 == srcfile.Read(tmprbuf,1)){ k = (unsigned char)tmprbuf[0]; k ^= (unsigned char)key[(i-(4+1+nsize/2))%mn]; } else{k = 0;} if(1 == fread(tmprbuf, sizeof(char), 1, srcfile)){//1 == srcfile.Read(tmprbuf,1)){ l = (unsigned char)tmprbuf[0]; l ^= (unsigned char)key[(i-(4+1+nsize/2))%mn]; jj = (j<<16) + (j^((k<<8)+ l)); } else{jj = (j<<16) + (j^((k<<8)+ 0));} *((unsigned int*)&tmpch) = jj;//32 bit fwrite( tmpch,sizeof(char),4, dstfile); //dstfile.Write(tmpch, 4);//32 bit } tmprbuf[3] = 0; for(i=0; i<nhsize*nvsize ; i++){ fread(tmprbuf, sizeof(char), 3, nekofile); fwrite( tmprbuf,sizeof(char),4, dstfile); } fclose(nekofile); fclose(srcfile);//.Close(); fclose(dstfile);//.Close(); }
その他の回答 (2)
- uyama33
- ベストアンサー率30% (137/450)
回答1;原始的だが以下のようにして扱いました。 #include "stdafx.h" #include <string.h> #include <stdlib.h> #include <stdio.h> #include <time.h> #include <math.h> typedef unsigned char uchar; typedef unsigned short ushort; typedef unsigned long DWORD; FILE* keyfile; FILE* srcfile; FILE* dstfile; FILE* nekofile; void bmp1(char* keyfn, char* pt, char* ct) // 暗号化 { int mode,klen; //,blen,rc; char c_mode[4], c_klen[8], c_key[64]; int nsize, fsize, sidesize; char FName[256], tmpfn[256], tmpfn2[256], nekofn[256], c; unsigned int j, k, l, jj; int i, mn; unsigned char tmpch[16]; unsigned char tmprbuf[16]; char key[64];//32]; unsigned char bmpHeader[54] = { 'B', 'M', /* [ 0] ファイルタイプ */ 54, 4, 0, 0, /* [ 2] ファイルサイズ 54+4*16*16=1078*/ 0, 0, 0, 0, /* [ 6] 予約 */ 54, 0, 0, 0, /* [10] ビットマップデータのシーク位置 */ 40, 0, 0, 0, /* [14] ここから始まるヘッダの高さ */ 16, 0, 0, 0, /* [18] ビットマップの幅 */ 16, 0, 0, 0, /* [22] ビットマップの高さ */ 0x01, 0, /* [26] プレーン数 */ 32, 0, /* [28] 1ピクセルあたりのビット数 (課題が4バイト指定されていたので32bitに変更) */ 0, 0, 0, 0, /* [30] 圧縮タイプ */ 0, 1, 0, 0, /* [34] ビットマップデータの長さ 16*16=256*/ 0, 0, 0, 0, /* [38] 水平解像度(px/m) */ 0, 0, 0, 0, /* [42] 垂直解像度(px/m) */ 0, 0, 0, 0, /* [46] カラーインデックス数 */ 0, 0, 0, 0, /* [50] 重要なカラーインデックス数 */ }; unsigned char bmpHeader2[54] = { 'B', 'M', /* [ 0] ファイルタイプ */ 54, 4, 0, 0, /* [ 2] ファイルサイズ 54+4*16*16=1078*/ 0, 0, 0, 0, /* [ 6] 予約 */ 54, 0, 0, 0, /* [10] ビットマップデータのシーク位置 */ 40, 0, 0, 0, /* [14] ここから始まるヘッダの高さ */ 16, 0, 0, 0, /* [18] ビットマップの幅 */ 16, 0, 0, 0, /* [22] ビットマップの高さ */ 0x01, 0, /* [26] プレーン数 */ 32, 0, /* [28] 1ピクセルあたりのビット数 (課題が4バイト指定されていたので32bitに変更) */ 0, 0, 0, 0, /* [30] 圧縮タイプ */ 0, 1, 0, 0, /* [34] ビットマップデータの長さ 16*16=256*/ 0, 0, 0, 0, /* [38] 水平解像度(px/m) */ 0, 0, 0, 0, /* [42] 垂直解像度(px/m) */ 0, 0, 0, 0, /* [46] カラーインデックス数 */ 0, 0, 0, 0, /* [50] 重要なカラーインデックス数 */ }; strcpy(nekofn,"nyanya2.bmp"); if( fopen_s(&nekofile, nekofn, "rb") != 0){ printf("Can not open neko file. \n"); return; } fseek(nekofile,0,0); fread(bmpHeader2, sizeof(char), 54, nekofile);//srcfile.Read(bmpHeader, 54); int nhsize = *((DWORD*)(&(bmpHeader2[18]))); int nvsize = *((DWORD*)(&(bmpHeader2[22]))); int nfsize = *((DWORD*)(&(bmpHeader2[2])));//54+24*256*166, 1ピクセルあたり24=3*8ビット if((keyfile = fopen(keyfn, "rt")) == NULL){ // printf("Can not find key file for encryption. \n"); return; } fgets( c_mode, 4, keyfile ); fgets( c_klen, 8, keyfile ); fgets( c_key, 64, keyfile ); fclose(keyfile); strcpy(key, c_key); mode = atoi(c_mode); klen = atoi(c_klen); mn = 8; if(klen == 128){ mn = 16; } if(klen == 192){ mn = 24; } if(klen == 256){ mn = 32; } if((srcfile = fopen(pt, "rb")) == NULL){ printf("Can not open plane file. \n"); return; }
- Wr5
- ベストアンサー率53% (2173/4061)
MFC使っていませんけどね…。 # VS2005Stdならあるので使える環境ではある。ただしC++をちゃんと習得しているわけではないが。 >char配列からのカラーbitmapの作成 そもそも、そのchar配列に入っているものってなんです? CBitmap::CreateBitmapIndirect()とかで作成することになるんじゃないですかね? API使ってHBITMAPでもいいのかもしれませんが。
補足
補足遅くなってすいません。 カメラメーカーAPIによってchar配列にはピクセル値が入ってくるようになっています。 その後調べているとSetDIBitsで出来そうな感じもあり組んでいるところです。 結果出ましたら報告させていただきます。
お礼
CreateCompatibleBitmapでDDBのHBITMAPを作成し、取得したバッファを24bitの形式の配列に格納しなおして(8bit/pixのバッファから24bitGBR/pixの配列)SetBitmapBitsをしたら無事表示できました。 いまいち、DIBとDDBの違いと、ファイルでのBitmapと表示するためのオブジェクトとしてのBitmapの違いが分かっていなかったようです。 ベストアンサーは丁寧にソースコードを回答していただいたuyama33とさせていただきます。 ありがとうございました!!
補足
補足遅くなってすいません。 質問にも書いたのですがファイルに落とせばいけそうなのですが、毎フレームファイルを作成していると時間のロスなので、ハンドルやクラスでの変換ができないかと思っています。 その後調べているとSetDIBitsで出来そうな感じもあり組んでいるところです。 結果出ましたら報告させていただきます。