文字列変換

[戻る]
ブラウンジェ 2008/09/08(月) 16:28:13
文字列変換についての質問です

以下の3個unsigend char型の文字列を

unsigend char *hogeA = 255;
unsigend char *hogeB = 0;
unsigend char *hogeC = 0;

連結させてint型に変換したいのですが、、、

0xff0000 (こんな感じ)

どうすればよいでしょうか?

宜しくお願いします。

たいちう 2008/09/08(月) 16:58:07
色々間違えてるけど、おそらくやりたいことはこんなことではないかと。

unsigned char hogeA = 255;
unsigned char hogeB = 0;
unsigned char hogeC = 0;
int x = (hogeA << 16) + (hogeB << 8) + hogeC;
printf("0x%x\n", x);

επιστημη [HomePage] 2008/09/08(月) 16:59:58
intは4byte/little-endianと決め付けていいなら:

#include <iostream>
#include <iomanip>

union int32 {
  int ival;
  unsigned char cval[4];
};

int main() {
  int32 x;
  x.cval[0] = 0; /* 下位から埋める */
  x.cval[1] = 0;
  x.cval[2] = 255;
  x.cval[3] = 0;
  std::cout << std::hex << x.ival << std::endl;
}

仲澤@失業者 2008/09/08(月) 17:02:17
つっこみどころ満載のソースと質問ですが、我慢しといて
こういうことでしょうか。

unsigned char hogeA = ( unsigned char )255;
unsigned char hogeB = ( unsigned char )0;
unsigned char hogeC = ( unsigned char )0;
char    buf[ 256];
sprintf( buf, "0x%02X%02X%02X", hogeA, hogeB, hogeC);

PATIO 2008/09/08(月) 18:09:37
ふむふむ。
データとしてlong型のデータにしたいのか、
単純に0x00ff0000と表示したいだけなのかで
話が変わりますね。
なので、質問時は出来るだけ詳しく取り違いが起こらないように
注意して書くのが吉です。

解答に関しては既にたくさん出ているので御自分の欲しい物から
どの方法が良いのかは考えてください。

ブラウンジェ 2008/09/08(月) 18:26:29
素人満載の質問で申しわけないです。
今までの流れを詳細に書かせて頂きます。
カメラ3台の映像を取得して内部で画像処理を施して
一画面で出力するソフトを作成しています。
当初は、仮想メモリにSetPixelして処理終了後BitBltしていましたが
フレームレートが遅いためにDIBで高速描画に切り替える事にしました。

抜粋で申し訳ないのですが、まずカメラから各ピクセルの
色情報を取得します。
m_pCamera[CameraNumber]->GetCurrentImage(m_pSnapImage);
m_pSnapImage[Num+2] -> R成分の取得(0-255)
m_pSnapImage[Num+1]  -> G成分の取得(0-255)
m_pSnapImage[Num+0]  -> B成分の取得(0-255)

以前はこの情報を仮想メモリに対して、SetPixelしていました。
現在はDIBで以下のように行っています

//DIBSection作成
hBitmap=::CreateDIBSection(hdc,&bmpInfo,DIB_RGB_COLORS,(void**)
&lpPixel,NULL,0);
hMemDC =::CreateCompatibleDC(hdc);

// 作成したDIBの選択
::SelectObject(hMemDC,hBitmap);

// 作成したDIBに取得したRGB色情報を格納していきたいのです。
例えばこのように。。。。
lpPixel[Xnum+Ynum*WIDTH] = 0x00ff0000; // 赤
代入するHex値の色情報の並びは以下になります。
0x00[予備]ff[R]00[G]00[B]

解らないのは、、、
取得した色情報以下RGB値を

m_pSnapImage[Num+2] -> R成分の取得(0-255)
m_pSnapImage[Num+1]  -> G成分の取得(0-255)
m_pSnapImage[Num+0]  -> B成分の取得(0-255)

Hex値で0x00[予備]ff[R]00[G]00[B]のルールに則り

lpPixel[Xnum+Ynum*WIDTH]に代入する方法です。

ちなみに二つの型は下記のようになります。

unsigned char* m_pSnapImage;
LPDWORD        lpPixel;

かもねぎ 2008/09/08(月) 20:31:51
ソース貼ったほうが速いかも。。。
本人のみぞ知る悩み・・

... 2008/09/08(月) 20:35:28
> Xnum+Ynum*WIDTH
> m_pSnapImage
> 
http://rararahp.cool.ne.jp/cgi-bin/lng/vc/vclng.cgi?print+200808/08080046.txt
これの変形(続き)と考えたらいいの?
もしそうなら、以前の書き込みの中に回答のヒントがある。

bun 2008/09/09(火) 09:33:28
DIBについては以下のホームページが詳しいです。
http://eternalwindows.jp/graphics/bitmap/bitmap00.html

もしかしたら、
[DIBセクション]ページにある[必ず4の倍数でなければならない]と言う
制約に引っかかっているのではないでしょうか?

rin 2008/09/09(火) 09:57:40
ビット配列に色データをいれたいときは
RGBQUAD って構造体が便利

PATIO 2008/09/09(火) 09:59:12
unsigned charのデータ3つをDWORDの形にまとめる方法は
既にたいちうさんが書かれていると思います。

シフト演算子が分からないならちゃんとC++の入門書で確認した方が
良いと思いますよ。
よくプログラムの上達は「習うより慣れろ」といいますけれど、
プログラムを組むには文法に関する知識はやはり必要です。
文法の部分を理解した上で「習うより慣れろ」ならわかりますけれど。

完全には覚え切れなくても「これは本のどこかに書いてあったなぁ」
くらいのレベルにはなっておいた方がいいです。

ブラウンジェ 2008/09/09(火) 12:40:18
επιστημη様、仲澤@失業者様、PATIO様、かもねぎ様、bun様、rin様
皆様ご指導ありがとうございました。
”PATIO様”のご指摘とおり”たいちう様”のご指導でうまくいきました。

lpPixel[x+y*WIDTH] = 
(m_pSnapImage[Num+2] << 16) + 
(m_pSnapImage[Num+1] << 8) + 
(m_pSnapImage[Num+0]);

他の方のアドバイスも今後の為に参考にさせて頂きます。
シフト演算子をもう少し勉強致します。

PS. SetPixel処理よりはるかに早いフレームレートが実現出来ました。

ブラウンジェ 2008/09/09(火) 14:55:37
[[解決]]
感謝感謝

maru 2008/09/09(火) 20:55:00
最近MICRA-C 2004を読んでいて知ったこと:未定義の動作32=
「式をシフトするビット数が負である場合、またはシフトされる式のビット数以上の場合
(6.3.7)」
とあるんだけど、unsigned charを8ビットや16ビットシフトしていいのかな?
キャストしてからシフトしないといけないような気が...
代入先が32ビットだからシフト前に汎整数拡張されるんですかね?

tetrapod 2008/09/09(火) 23:23:54
MISRA を読むくらいのレベルなら言語規格書を直接読むべし読むべし読むべし
シフト演算の解説によると (JIS X 3010:2003 6.5.7)
・両オペランドを汎整数拡張する
・結果の型は左オペランドを汎整数拡張した結果の型である
・右オペランドが負数または
 *左オペランドを汎整数拡張した結果の型のビット数以上* である場合は未定義
となっている。

> unsigned charを8ビットや16ビットシフトしていいのかな?
良い (int が16bitより大きい処理系であれば)
(unsigned char を汎整数拡張した結果 int になるとして)

代入先など無関係。double x=3/4; とかと同じだぞ。

maru 2008/09/16(火) 19:56:16
tetrapod様
丁寧な解説、ありがとうございました。

> MISRA を読むくらいのレベルなら言語規格書を直接読むべし読むべし読むべし
分かってはいるんですがねぇ...

古いスレッドには追加発言できません。