• ベストアンサー

memcpyで画像を送りたいのですが・・

DirectXを使って 片方の画像(テクスチャ)の一部を、もう片方に送りたいのですが・・ 画像を直接送るだけなら、縦横ピクセル分のforで ------------------------------ memcpy((BYTE*)Rect_tgt.pBits + Rect_tgt.Pitch * i + j*4, (BYTE*)Rect_base.pBits + Rect_base.Pitch * i + j*4, 4); ------------------------------ これで送れるのですが、RGBAそれぞれを確認しながら 特定の色を置き換えたり、抜き色操作したくて ------------------------------ BYTE psend[4]; psend[0] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*1; psend[1] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*2; psend[2] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*3; psend[3] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*4; memcpy((BYTE*)Rect_tgt.pBits + Rect_tgt.Pitch * j + i*4, &psend, 4); ------------------------------ などと色々いじりまわしてみているのですが、 一色で塗り潰した画像を使っても、変なパターン模様になってしまいます。 ------------------------------ psend[0] = 255; psend[1] = 255; ........ ------------------------------ 等と直接指定すれば、ちゃんとそれに応じた色が書き出されるので 他の部分は正常だと思うのですが・・ どうすればRGBA1つ1つの色を正しく受け取れるでしょうか?

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

  • ベストアンサー
  • goosyu
  • ベストアンサー率58% (36/62)
回答No.4

補足ありがとうございました。やりたいことがなんとなくわかりました。指摘点は変更ありませんが,サンプルを訂正します。 for (j = 0;j < tgt_height;j++) { for (i = 0;i < tgt_width; i++) { BYTE psend[4]; BYTE *pSrc; pSrc = &((BYTE *)Rect_base.pBits)[Rect_base.Pitch * j + i * 4]; psend[0] = pSrc[0];//B psend[1] = pSrc[1];//G psend[2] = pSrc[2];//R psend[3] = 255;//A // 正常な直接転送 memcpy((BYTE*)Rect_tgt.pBits + Rect_tgt.Pitch * i + j*4, (BYTE*)Rect_base.pBits + Rect_base.Pitch * i + j*4, 4); memcpy((BYTE*)Rect_tgt.pBits+Rect_tgt.Pitch * j + i*4, &psend, 4); //本体 } }

zaxs5968
質問者

お礼

ありがとうございます・・! 動いて欲しかった通りに動いてくれました・・! BYTE *pSrc; pSrc = &((BYTE *)Rect_base.pBits)[Rect_base.Pitch * j + i * 4]; 一応ポインタやアドレス渡し等の基礎は一通り習ったはずなのですが、 今の私には何をどうやってるのか解らない構文・・orz もう質問の本題は解決できてしまったのでお礼を――なのですが、 これを理解しないとまた似たような質問をここにしてしまいそうなので、 よろしければ pSrc = &((BYTE *)Rect_base.pBits)[Rect_base.Pitch * j + i * 4]; で何が起きているのか軽くでいいので、教えて頂けると幸いです orz

その他の回答 (4)

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.5

【説明】  「pSrc = &((BYTE *)Rect_base.pBits)[Rect_base.Pitch * j + i * 4];」は「pSrc = (BYTE *)Rect_base.pBits + Rect_base.Pitch * j + i * 4;」と同じ結果になると思います。  イメージとしては,「&Rect_base.pBits[Rect_base.Pitch * j + i * 4]」と記述した方がわかりやすいかなと思いコーディングしましたが,「Rect_base.pBits」は「void *」のためキャストが必要となり複雑になったかもしれません。  次のように式を分けるとたぶん読みやすくなります。   pSrc = (BYTE *)Rect_base.pBits;   pSrc = &pSrc[Rect_base.Pitch * j + i * 4];  一応,提供ソースを最小限修正するコードものせておきます。 psend[0] = *((BYTE *)(Rect_base.pBits)+Rect_base.Pitch * j + i*4);//B psend[1] = *((BYTE *)(Rect_base.pBits)+Rect_base.Pitch * j + i*4+1);//G psend[2] = *((BYTE *)(Rect_base.pBits)+Rect_base.Pitch * j + i*4+2);//R psend[3] = 255;//A  または psend[0] = ((BYTE *)(Rect_base.pBits))[Rect_base.Pitch * j + i*4];//B psend[1] = ((BYTE *)(Rect_base.pBits))[Rect_base.Pitch * j + i*4+1];//G psend[2] = ((BYTE *)(Rect_base.pBits))[Rect_base.Pitch * j + i*4+2];//R psend[3] = 255;//A  となります。

zaxs5968
質問者

お礼

pSrc = (BYTE *)Rect_base.pBits; pSrc = &pSrc[Rect_base.Pitch * j + i * 4]; なるほど。 渡しの勉強不足を自覚しましたが、この書式の意味が解りました・・! 色々と親切丁寧に教えて頂いて、本当にありがとうございます・・! この書式、自分でも使えるよう頑張ります。ありがとうございました~!o(_ _)o

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.3

 Rect_base.pBitsがD3DLOCKED_RECT型のメンバであればvoid *なので値はテクスチャの先頭アドレスになります。  この為「Rect_base.pBits + Rect_base.Pitch * j + i*1」ではアドレスの計算結果になります。  それを「psend[0]」に入れてもアドレスの指す値にはなりません。  書くとすれば「psend[0] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*1;」は 「psend[0] = ((BYTE*)Rect_base.pBits)[ Rect_base.Pitch * j + i*1];」となります。  もう一点問題点は「i*1」「i*2」「i*3」「i*4」の計算です。参照位置の計算は「i+0」「i+1」「i+2」「i+3」が正しいと思います。  参考までに次のようなソースでたぶん実施したいことができると思います。 // 1ピクセルが4バイトで構成されている場合のサンプル BYTE *pSrc; // pBitsの値が格納 long index; pSrc = (BYTE *)Rect_base.pBits; for (j= 0;j<Height;j++) { // Heightは元のソースに合わせて置き換えてください for (i= 0;i<Width;i++) { // Widthは元のソースに合わせて置き換えてください BYTE psend[4]; index = Rect_base.Pitch * j + i * 4; psend[0] = pSrc[ index ]; psend[1] = pSrc[ index + 1 ]; psend[2] = pSrc[ index + 2 ]; psend[3] = pSrc[ index + 3 ]; // 値変更する処理をここに書く memcpy(pSrc, &psend[0], 4); } }

zaxs5968
質問者

お礼

ご回答ありがとうございます。

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.2

iの増加量とかわからないので,可能であれば2重のfor文を含めたソースを開示してください。Rect_base.pBitsとRect_base.Pitchn具体的な値があれば確認しやすいです。

zaxs5968
質問者

お礼

ご回答ありがとうございます。 ---------------------------------------------- D3DLOCKED_RECT Rect_tgt; panels->pTex[1]->LockRect(0, &Rect_tgt, NULL, D3DLOCK_DISCARD); panels->pTex[1]->LockRect(0, &Rect_tgt, NULL, 0); D3DLOCKED_RECT Rect_base; pFontTex->LockRect(0, &Rect_base, NULL, D3DLOCK_DISCARD); pFontTex->LockRect(0, &Rect_base, NULL, 0); for (j = 0;j < tgt_height;j++) { for (i = 0;i < tgt_width; i++) { BYTE psend[4]; psend[0] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*1;//B psend[1] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*2;//G psend[2] = (BYTE)Rect_base.pBits + Rect_base.Pitch * j + i*3;//R psend[3] = 255;//A // 正常な直接転送 memcpy((BYTE*)Rect_tgt.pBits + Rect_tgt.Pitch * i + j*4, (BYTE*)Rect_base.pBits + Rect_base.Pitch * i + j*4, 4); memcpy((BYTE*)Rect_tgt.pBits + Rect_tgt.Pitch * j + i*4, &psend, 4); //本体 } } pFontTex->UnlockRect(0); panels->pTex[1]->UnlockRect(0); ---------------------------------------------- こうなってます、値は Rect_base.Pitch = 4804 Rect_base.pBits = 0x04b90040 Rect_tgt.Pitch = 724 Rect_tgt.pBits = 0x001f81a0 となっていました。宜しくお願いします orz

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.1

>memcpy((BYTE*)Rect_tgt.pBits + Rect_tgt.Pitch * j + i*4, &psend, 4); 第2引数に & が付いているのは、どうしてですか? 第3引数は転送バイト数を指定します。本当に4バイトでいいのですか?

zaxs5968
質問者

お礼

ご回答ありがとうございました。 他のサンプルからの切り張りでイマイチ理解してなくて申し訳ないです; もっと勉強しようと思います;