dポイントプレゼントキャンペーン実施中!

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

A 回答 (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();

}

この回答への補足

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

補足日時:2013/12/24 16:04
    • good
    • 0
この回答へのお礼

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

お礼日時:2014/01/18 10:05

回答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;
}
    • good
    • 0

MFC使っていませんけどね…。


# VS2005Stdならあるので使える環境ではある。ただしC++をちゃんと習得しているわけではないが。

>char配列からのカラーbitmapの作成

そもそも、そのchar配列に入っているものってなんです?

CBitmap::CreateBitmapIndirect()とかで作成することになるんじゃないですかね?
API使ってHBITMAPでもいいのかもしれませんが。

この回答への補足

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

補足日時:2013/12/24 16:02
    • good
    • 0

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