• ベストアンサー

C++ bmp 透過処理

machongolaの回答

  • ベストアンサー
回答No.3

 こんばんは。  昔、ゲームプログラムの書籍に、unsigned long型のバッファ同士を四角形に見立てて、コピーし合う様な手段が紹介されていました(最終的にはOSが持つ描写関数へ渡されます)。  動作確認はしていますが、アラも在りそうなので、以下参考程度で。 struct IMAGE { int width; int height; unsigned long* image; }; static void Fill(IMAGE* p, int x, int y, int w, int h, unsigned long color) { x = std::min(std::max(0, x), p->width); y = std::min(std::max(0, y), p->height); w = std::min(std::max(0, w), p->width); h = std::min(std::max(0, h), p->height); for(int dy = y; dy < h; ++dy) { for(int dx = x; dx < w; ++dx) { p->image[dx + dy * p->width] = color; } } } static void Create(IMAGE* p, int width, int height, unsigned long color) { p->width = width; p->height= height; p->image = new unsigned long[p->width * p->height]; ::Fill(p, 0, 0, width, height, color); } static void Delete(IMAGE* p) { const IMAGE zero = {0}; delete [] p->image; *p = zero; } static void BitBlt(IMAGE* pdst, int xpos, int ypos, const IMAGE* psrc, unsigned long key) { const int x = std::max(0, xpos); const int y = std::max(0, ypos); const int x2 = xpos < 0 ? -xpos : 0; const int y2 = ypos < 0 ? -ypos : 0; for(int sy = y2, dy = y; (sy < psrc->height) && (dy < pdst->height); ++sy, ++dy) { for(int sx = x2, dx = x; (sx < psrc->width) && (dx < pdst->width); ++sx, ++dx) { const int dpos = dx + dy * pdst->width; const int spos = sx + sy * psrc->width; if(psrc->image[spos] == key) continue; pdst->image[dpos] = psrc->image[spos]; } } } //ココは大きく環境依存する static void SaveOSDepend(const IMAGE* p) { #pragma pack(push, 1) struct { BITMAPINFOHEADER bih; DWORD f[3]; } info = {0}; #pragma pack(pop) info.bih.biSize = sizeof(info.bih); info.bih.biBitCount = 32; info.bih.biPlanes = 1; info.bih.biCompression = BI_BITFIELDS; info.bih.biWidth = p->width; info.bih.biHeight = p->height; info.bih.biSizeImage = info.bih.biWidth * info.bih.biHeight * (info.bih.biBitCount / 8); info.f[0] = 0xff0000; info.f[1] = 0x00ff00; info.f[2] = 0x0000ff; BITMAPFILEHEADER bfh = {0}; bfh.bfType = *((LPWORD)"BM"); bfh.bfOffBits = sizeof(bfh) + sizeof(info); bfh.bfSize = bfh.bfOffBits + info.bih.biSizeImage; FILE* fp = ::fopen("test.bmp", "wb"); ::fwrite(&bfh, sizeof(bfh), 1, fp); ::fwrite(&info, sizeof(info), 1, fp); for(int y = info.bih.biHeight - 1; y >= 0; --y) { const int pos = y * info.bih.biWidth; ::fwrite(&p->image[pos], info.bih.biWidth, info.bih.biBitCount / 8, fp); } ::fclose(fp); } int main(int argc, _TCHAR* argv[]) { IMAGE imgA; IMAGE imgB; //画像A 緑色で作成 ::Create(&imgA, 128, 64, 0xff00); //画像B 赤色で作成 ::Create(&imgB, 256, 36, 0xff0000); //画像B 5ピクセル余白を残して、白色で塗る(赤色の枠に白色の内部見たいな感じ) ::Fill(&imgB, 5, 5, 256 - 5, 36 - 5, 0xffffff); //白色を透明色に指定して、画像Aに画像Bを転送する ::BitBlt(&imgA, 20, -2, &imgB, 0xffffff); //32bit(windows bitmap)に変換セーブ ::SaveOSDepend(&imgA); //画像A,Bの後始末 ::Delete(&imgA); ::Delete(&imgB); return 0; }

ShimantoGa
質問者

お礼

回答ありがとうございます。 APIにLoadImage関数が存在していたので、透過処理も何かbmp専用の関数が存在するのかと思っていました。 >動作確認はしていますが、アラも在りそうなので、以下参考程度で。 補足をいただきたい点がございます。 #pragma pack(1)を使用する理由: 「BITMAPINFOHEADER構造体の仕様」と「パッキング」が関係しているらしいということはわかりました。 しかしそれ以上の情報を発見できなかったため、 #pragma pack(push, 1) struct{ BITMAPINFOHEADER bih; DWORD f[3]; } info = {0}; #pragma pack(pop) のコードを解析できません。 宜しければ何をしているのか教えていただけないでしょうか。

関連するQ&A

  • イラストレータで透過処理すれば解決?

    はじめまして、野沢と言います。 イラストレータでアイコンを作成して(A)、 一旦、JPEGなどの形式で保存して、後日、 さらにそれを別の画像(B)と合わせる際に Aの画像が正方形の形で、いらない白い部分が 表示されてしまうことがあります。 画像の部分だけを表示させるには保存する際か、 または、透過処理で特別な処理をすればいいのでしょうか?

  • 透過動画と動画の合成処理

    静止画像で画像Aと透過GIF画像Bを重ねるように, 動画Aと動画Bの2種の花火動画(それぞれ10秒程度;解像度,コーデック等は同じ)をオーバーレイにして2種の花火を1回で打ち上げたように合成したいと考えています.  最初にクロマキー処理を考えました.しかし,背景色は単一ではありません.他の方法として,動画Bの必要な領域を静止画として書き出し,1フレームずつ単一色で塗りつぶして行くことも考えましたが,作業量の多さを思うと尻込みをしています. 今後も特にその他の動画処理をしていこうという事はないので,高価なソフトの購入は今のところ考えておりません(これがあればできるというのがあればご紹介ください.). そこで質問なのですが, 1)動画A,Bを同じ解像度で,必要な動き以外の背景を単一化してオーバーレイ等が比較的簡単にできるソフトがあるかどうか. 2)動画処理で,必要な領域以外の色を比較的簡単に単一にできるソフトがあるかどうか. 3)静止画(BMP)処理で,ドットの色を抽出し,選択した色以外を希望の色に変換してくれるようなソフトがあるかどうか. 4)その他で比較的簡単な方法があるのかどうか. ご教示お願いします.  

  • C言語でBMP(16bit)を扱う方法

    組み込みソフトの作成を行なっており、液晶に画像を表示するソフトを 作りたいと思っております。 16bitのビットマップ画像をC言語のソースにするにはどうすればよいでしょうか? interface2011年5月号の付録(Renesas RX62N)を使用して、3.5インチQVGAのTFT液晶に 画像を表示したいと思っているのですが、自分で用意した16ビットのビットマップ画像を どうすればC言語ソースに落とせるのかがわかりません。 付録のサンプルプログラムでは、pct_data[]={65535,65535,・・・・}; と各ドットを16bitで表現した配列になっているのですが、ビットマップデータからこのような 配列の作成方法を教えて頂けると助かります。 よろしくお願いいたします。

  • bmpファイルが開きません。

    ウェブサイトからの画像などは(ビットマップ)Adobeで 開くのですが、友人からHotmailへ送ってもらった ビットマップ イメージ画像が開きません。 ‐‐‐ ファイル形式用プラグインはファイルを 解析することができません。 従って、「◯◯◯◯.bmp」を 開く事ができませんでした。 ‐‐‐‐ このように表示されます。 宜しくお願いします。(;^_^A

  • プログラミング(c#)で画像処理に関して

    質問させてください。 c#で画像処理に関してです。 picturBox上の画像や図形を、ビットマップ変換し、 ・ラベリング ・エッジ検出 等を行いたいのですが、そういった方法(コードについて)が説明されている サイトは無いでしょうか? よろしくお願いします。

  • C++ 画像処理

    C++で画像処理を行おうと思っています。 当初jpegの入出力を試す予定でしたが、検索しても出てくるのがbmpばかりで標準関数はjpegに対応していないのかなと思いました。 C++の画像処理全般に関して詳しく紹介しているサイトや本などはありませんでしょうか。

  • テキストファイルやcsvファイルで読み込んだデータを使ってjavascriptで処理する方法

    javascript初心者です。 いろいろと調べたのですが、イマイチよく分からないので質問させてください。 テキストファイルやcsvファイルを読み込んで、 javascriptで判定処理をしたいと思います。 例えば、 A地区,1 B地区,0 C地区,4 ・・・ といったデータを読み込んで、 javascriptで「0なら○地区には画像Aを表示、 それ以外なら○地区には画像Bを表示する」 という形で処理したいです。 でも、 ・どうやってファイルを読み込むのか ・読み込んだデータをどのようにして配列へ入れるのか がよく分からないです。 これらのページ 「http://q.hatena.ne.jp/1195740627」 「http://www.openspc2.org/JavaScript/Ajax/Ajax_study/chapter03/002/index.html」 のような方法を参考にすれば実現可能なのでしょうか。

  • ビットマップ画像 54 + 1024byteヘッダ

    ある課題で、以下の画像をWindows 上で処理しなければならないのですが、 512×424+(54 + 1024)= 218166byte の大きさで、256 色ビットマップのようです。 表題にある通り、ヘッダが54byte + 1024byte あるようで、 この画像と同じフォーマットで、リサイズしたいのですがどのような規則でヘッダを作ればよいかわからず途方に暮れています。 そもそも、ビットマップヘッダは54byte 以外のものもあるのでしょうか。 ご助言いただけますでしょうか。 なお、mspaint では正しく開けます。 <画像> https://dotup.org/uploda/dotup.org1817556.bmp

  • 画像処理の仕方

    C++を使ってモノクロのビットマップの画像の各ピクセルの輝度を数値化してテキスト形式で出力る物を作りたいと思っているんですが、ビットマップに対してどう処理してやればいいか分りません。誰か教えてください。

  • C#での印刷機能に関して

    C#での印刷機能に関して C#を用いて開発を行っていますが、その中で印刷ボタンを設け、印刷処理 を行いたいと考えています。 印刷自体の処理はある程度調べて実現しましたが、フォーマットを指定して 出力したいと考えています。 例えば、、、この位置にこの変数の値を出力したい等。。。 アクティブレポートのようなツールを購入すれば可能かと思われますが、標準 のVisualStudio2008の機能で実現できないかと考えて います。 何か良い方法はありますでしょうか。。。 初歩的な質問で申し訳ありませんが、教えて下さい。 よろしくお願いします。