• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:MFCでのBITMAP作成について)

MFCでのBITMAP作成について

このQ&Aのポイント
  • VC++2005MFCで開発しています。カメラからの画像入力の部分を作成しているのですがchar配列からのカラーbitmapの作成の仕方が分かる方いませんでしょうか?
  • 直接ファイルに書き込む方法ですとフォーマット通りに書き込めば良いとは思うのですが、画面表示をしたいのでCBitmap又はHBitmapで取得したいです。
  • 調べていると、モノクロだとSepBitmapBitsでできそうです。しかし、msdnを見るとカラーの場合はSetDIBitsを使用しろとあるのですが、SetDIBitsの項を見ると何か思っている用法と違いそうです。また、VC++.NETですとDrawing::Bitmap(( width, height, stride, format, scan0);でフォーマットを指定して作成できそうなのですが、それに相応するようなものはないかと探しているのですが見つかりません。すいませんがご教授お願いします。

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

  • ベストアンサー
  • uyama33
  • ベストアンサー率30% (137/450)
回答No.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(); }

nori1112
質問者

お礼

CreateCompatibleBitmapでDDBのHBITMAPを作成し、取得したバッファを24bitの形式の配列に格納しなおして(8bit/pixのバッファから24bitGBR/pixの配列)SetBitmapBitsをしたら無事表示できました。 いまいち、DIBとDDBの違いと、ファイルでのBitmapと表示するためのオブジェクトとしてのBitmapの違いが分かっていなかったようです。 ベストアンサーは丁寧にソースコードを回答していただいたuyama33とさせていただきます。 ありがとうございました!!

nori1112
質問者

補足

補足遅くなってすいません。 質問にも書いたのですがファイルに落とせばいけそうなのですが、毎フレームファイルを作成していると時間のロスなので、ハンドルやクラスでの変換ができないかと思っています。 その後調べているとSetDIBitsで出来そうな感じもあり組んでいるところです。 結果出ましたら報告させていただきます。

その他の回答 (2)

  • uyama33
  • ベストアンサー率30% (137/450)
回答No.2

回答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)
回答No.1

MFC使っていませんけどね…。 # VS2005Stdならあるので使える環境ではある。ただしC++をちゃんと習得しているわけではないが。 >char配列からのカラーbitmapの作成 そもそも、そのchar配列に入っているものってなんです? CBitmap::CreateBitmapIndirect()とかで作成することになるんじゃないですかね? API使ってHBITMAPでもいいのかもしれませんが。

nori1112
質問者

補足

補足遅くなってすいません。 カメラメーカーAPIによってchar配列にはピクセル値が入ってくるようになっています。 その後調べているとSetDIBitsで出来そうな感じもあり組んでいるところです。 結果出ましたら報告させていただきます。

関連するQ&A

専門家に質問してみよう