お世話になります。

VC 2005で開発しているC++で教えていただきたい事が有ります。

PictureboxBの上にPictureboxAを透過率50%位で重ねて表示したいのですが、
Pictureboxのプロパティ等で一括で指定できないでしょうか?
出来ない場合、画像を一括で透過処理する方法が有りましたら教えていただけないでしょうか
※ ググって、単色を透過するのは、色々見つけたのですが、画像全体を透過する方法を見つけることが出来ませんでした。

現状は単純にファイル(写真)を読み込んで、PictureboxのImageに格納しているだけです。
※将来的には、PictureboxAをドラッグで移動させたいので、背景画像(PictureboxB)との位相を取る方法以外でお願いいたします。

Bitmap^ PhotBMP = gcnew Bitmap(filename);
// この間にサイズ変更&位置合わせの処理が有りますが、記載を省略させていただいております。
PictureboxA->Image = PhotBMP;

このQ&Aに関連する最新のQ&A

A 回答 (2件)

// No.1 の続きです。

長くて申し訳ない

Bitmap^ back;
Graphics^ backGraphics;
void UpdateBuffer(){
if(back==nullptr){
back=gcnew Bitmap(Width,Height);
backGraphics=Graphics::FromImage(back);
}else if(back->Width!=Width||back->Height!=Height){
delete backGraphics;
delete back;
back=gcnew Bitmap(Width,Height);
backGraphics=Graphics::FromImage(back);
}
}

protected:
virtual void OnPaintBackground(PaintEventArgs^ e) override{
ContainerControl^ container=dynamic_cast<ContainerControl^>(Parent);
if(container!=nullptr){
this->UpdateBuffer();
backGraphics->Clear(BackColor);

Rectangle rect=e->ClipRectangle;
rect.Intersect(Rectangle(Point::Empty,this->Size));
if(!rect.IsEmpty){
this->DrawBackgroundControl(backGraphics,rect,container,Point(-Location.X,-Location.Y));

int i0=container->Controls->IndexOf(this);
if(i0>=0){
for(int i=container->Controls->Count;--i>i0;){
Control^ ctrl=container->Controls[i];
Point offset=Point(
ctrl->Location.X-this->Location.X,
ctrl->Location.Y-this->Location.Y);

Rectangle rect2=rect;
rect2.Intersect(Rectangle(offset,ctrl->Size));
if(!rect2.IsEmpty)
this->DrawBackgroundControl(backGraphics,rect2,ctrl,offset);
}
}
}
e->Graphics->DrawImageUnscaled(back,0,0);
}else{
this->PictureBox::OnPaintBackground(e);
}
}
};

//-------------------------------------
// 使用例

public ref class Form1:public Form{
public:
Form1(){
SetStyle(ControlStyles::SupportsTransparentBackColor,true);

SuspendLayout();

Image^ image=Image::FromFile("test1.png"); // 適当な画像

// ★PictureBox の代わりに上で定義したTransparentPictureBox を使う
TransparentPictureBox^ pictureBoxA=gcnew TransparentPictureBox;
pictureBoxA->Location=System::Drawing::Point(10,10);
pictureBoxA->Size=System::Drawing::Size(100,100);
pictureBoxA->SizeMode=PictureBoxSizeMode::StretchImage;
pictureBoxA->Image=image;
pictureBoxA->Opacity=0.3f; // ★プロパティ Opacity に不透明度 (0.0f = 完全に透明、1.0 = 完全に不透明) を指定。
Controls->Add(pictureBoxA);

PictureBox^ pictureBoxB=gcnew PictureBox;
pictureBoxB->Location=System::Drawing::Point(60,60);
pictureBoxB->Size=System::Drawing::Size(100,100);
pictureBoxB->SizeMode=PictureBoxSizeMode::StretchImage;
pictureBoxB->Image=(Image^)image->Clone();
Controls->Add(pictureBoxB);

this->Size=System::Drawing::Size(200,200);
BackColor=Color::FromArgb(0xFF,0xDD,0xDD,0xFF);

ResumeLayout();
}

public:
static void Main(){
Application::Run(gcnew Form1());
}
};

int main(){
Form1::Main();
return 0;
}
    • good
    • 0
この回答へのお礼

ありがとうございます。

サンプルを作成して動作確認までしていただけるなんて、
本当に助かりました。

お礼日時:2014/07/07 10:29

簡単にはできないみたいですね…。



(1) 画像を透過して半透明にするだけなら http://dobon.net/vb/dotnet/graphics/hadeinimage. … にあります。
しかし、これを PictureboxA->Image に指定しても pictureBoxA の背景色 (~灰色) が透けるだけです。
更に、コントロールの背景色を「透明」にする方法として http://msdn.microsoft.com/ja-jp/library/wk5b13s4(v=vs.110).aspx がありますが、これの実態は親コントロール (Form) の背景を自コントロールの背景として使用するというだけの物で、兄弟コントロール (PictureboxB) は映り込んでくれません。

(2) 強引に PictureboxA 自体を「透過」させるのを実装してみました (下のコード)。(実は他に綺麗で簡単な方法があるかも知れませんが。)

【説明】
PictureBox から派生クラスを作って PictureBox の振る舞いを一部変更しています。
前半部分は (1) で紹介した URL の方法で、指定した画像の半透明版を作成しています。
後半部分は背景を描き込む関数 PictureBox::OnPaintBackground を overload して、背景として無理矢理他のコントロールを描画しています。

一応動作する事は確かめましたが、適当に書いたので効率面で問題があります。バグも在るかも知れませんので、使うなら注意深く使って下さい…。

--------------------
#using "System.dll"
#using "System.Drawing.dll"
#using "System.Windows.Forms.dll"

using namespace System::Windows::Forms;
using namespace System::Drawing;

public ref class TransparentPictureBox:public PictureBox{
public:
TransparentPictureBox(){
this->InitializeBackground();
this->InitializeForeground();
}

protected:
~TransparentPictureBox(){
this->DeleteBackground();
this->DeleteForeground();
}

//-------------------------------------
// 前景を半透明にする部分
private:
void InitializeForeground(){
this->imageAttributes=gcnew System::Drawing::Imaging::ImageAttributes;
this->Opacity=1.0f;
}
void DeleteForeground(){
this->Image=nullptr;
}

float opacity;
System::Drawing::Imaging::ImageAttributes^ imageAttributes;
public:
property float Opacity{
void set(float value){
if(opacity==value)return;

System::Drawing::Imaging::ColorMatrix^ cm=gcnew System::Drawing::Imaging::ColorMatrix;
cm->Matrix00 = 1;
cm->Matrix11 = 1;
cm->Matrix22 = 1;
cm->Matrix33 = value;
cm->Matrix44 = 1;
imageAttributes->SetColorMatrix(cm);
opacity=value;
this->UpdateAlphaImage();
}
float get(){return opacity;}
}

private:
System::Drawing::Image^ original;
public:
property System::Drawing::Image^ Image{
void set(System::Drawing::Image^ value){
if(this->original==value)return;
this->original=value;
this->UpdateAlphaImage();
}
System::Drawing::Image^ get(){return this->original;}
}

private:
Bitmap^ alphaImage;
void UpdateAlphaImage(){
if(this->alphaImage!=nullptr){
delete alphaImage;
alphaImage=nullptr;
this->PictureBox::Image=nullptr;
}
if(original!=nullptr){
alphaImage=gcnew Bitmap(original->Width,original->Height);
{
Graphics^ g=Graphics::FromImage(alphaImage);
g->DrawImage(
original,Rectangle(Point::Empty,original->Size),
0,0,original->Width,original->Height,GraphicsUnit::Pixel,imageAttributes);
delete g;
}
this->PictureBox::Image=alphaImage;
}
}

//-------------------------------------
// 背景に他のコントロールを描き込む部分

System::Reflection::MethodInfo^ methodOnPaint;
System::Reflection::MethodInfo^ methodOnPaintBackground;
void InitializeBackground(){
System::Reflection::BindingFlags flags
=System::Reflection::BindingFlags::Instance
|System::Reflection::BindingFlags::Public
|System::Reflection::BindingFlags::NonPublic;
this->methodOnPaint=Control::typeid->GetMethod("OnPaint",flags);
this->methodOnPaintBackground=Control::typeid->GetMethod("OnPaintBackground",flags);
}
void DeleteBackground(){
delete backGraphics;
delete back;
}

void DrawBackgroundControl(Graphics^ g,Rectangle rect,Control^ control,Point offset){
g->SetClip(rect);
g->TranslateTransform(offset.X,offset.Y);
rect.Offset(-offset.X,-offset.Y);
try{
array<System::Object^>^ args=gcnew array<System::Object^>{gcnew PaintEventArgs(g,rect)};
this->methodOnPaintBackground->Invoke(control,args);
this->methodOnPaint->Invoke(control,args);
}catch(...){}
g->TranslateTransform(-offset.X,-offset.Y);
g->ResetClip();
}

// 続く…

参考URL:http://dobon.net/vb/dotnet/graphics/hadeinimage. …
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qイラストの画像が乱れてしまうのですが・・・

私はホームページNinja2003を使っているのですが、イラストを載せたページをブラウザでプレビューすると必ず画像が乱れてしまいます。保存方法が変なのかと思い、見てみたらBMPで保存していました。その他にも、web用保存をしてみたのですがBMPよりも乱れてしまいます。他のサイトを見ていると画像が乱れたりしていないのですが、何故か凄く乱れてしまいます。ネット上で画像が乱れずに済む最適の保存方法を教えて下さい。
Win XPを使用しています。

Aベストアンサー

画像が乱れるという意味がちょっとあいまいなのですが・・・
どのように乱れているのでしょうか?
単にJPEGやGIFに変換して画質が劣化しているのか、ページ画像を貼り付ける際に画像を拡大縮小して乱れて見えるのか。

前者なら、PhotoshopのWeb用に保存で画質や色数をいじるとなおると思います。
後者なら、画像はHTMLでは基本的に拡大縮小して表示しないようにした方がいいです。
Photoshopで出力したそのサイズをそのまま使用するのがいいです。

QVC++6.0からVC++.NET2005へ移植

VC++6.0で作成したプログラムをVC++.NET2005に移植しました。
ビルドを行うと『fatal error LNK1104:ファイル'mfc42.lib'を開くことができません。』のエラーが出てしまいます。
ソリューションのプロパティを見てもどこで「mfc42.lib」の参照を定義しているのか分かりません。
どこで「mfc42.lib」の参照を定義しているのか教えてください。また、対策を教えてください。

Aベストアンサー

VC++.NET2005のエディションをお教えください。
Express Editionでは、リソースエディタがない、
ATL, MFCが使えないなどの制限がいくつか存在します。

また、VC2005などでは.NET Frameworkの開発が前提となっており
WIN32APIを使用する場合などについては、Platform SDKを
インストールする必要があります。

Qスカパー光 AXN HDだけ画像が乱れる

スカパー光 AXN HDだけ画像が乱れる

最近スカパーの光接続に変更し、色々なチャンネルをHDD録画してみていますが、AXNのドラマだけ画像(たまに音声)が乱れます。

1日或いは一回だけではなく、10日以上前から色々なスカパーHDチャンネルを見ていますが、このように画像が乱れるのはAXNだけです。

画像の乱れ方は、サテライト(アンテナディッシュでの衛星受信)利用時に雨が降って画像が乱れるのとちょっと似ている感じです。光接続なので雨などは関係ないと思うのですが・・・。

光接続はインターネット(ホームタイプ200MB独占)も兼用していますが、ネット接続で何か大きな負荷がかかるようなことは行っておらず、時間帯や日にちに限らず画像が乱れるのがAXNのハイデフニションだけなのでとても不思議です。

どなたか原因がわかるかたいらっしゃいましたらお願いします。

Aベストアンサー

特定のチャンネルだけ映りがおかしい場合は送信側に原因があることもありえますので、とりあえずはカスタマーセンターに相談されてはいかがでしょうか?

QVC++2005 VC++6.0で使えた関数がつかえない?(たとえば、GetModuleFileNameとか、、)

VC++超超初心者です。

いままであったVC++6.0で利用できていた、VC++2005で
GetModuleFileNameができなくなりました。
(利用できないことなんて、ないと思いますが、、、)

何か宣言とかinclude文とか必要なのでしょうか。

すみませんが、よろしくお願いします。

Aベストアンサー

VC++2005無料版にはPlatformSDKが別になっているのでそのままでは使えません
別にPlatformSDKをインストールしてVC++2005の設定を変える必要があります
VC++2008では無料版にもSDKが付属しています

QVHSビデオの画像の乱れについて。

先日、VHSビデオをDVDにダビングしようとビデオを見ていたところ、突然映像に波のような乱れが生じてしまい上手く移し変えることができませんでした。
デッキの不調かと思い、ヘッドクリーナ(乾式)をかけてみましたが一向に良くなる気配はありません。
何度か試して見ましたが、だいたい同じ場所で画像が乱れてしまいます。
この原因についてお伺いしたいのですが、もう2年ほどビデオデッキを使用していなかったため汚れが落ちないためなのか。
それとも過去に何度も見返していた部分のみ、テープが伸びたなどの理由で画像が乱れるのか。

今まで画像が乱れてしまったり伸びたりした経験がないもので、
どういった状態になるのかも加えて教えていただきたいです。
知っている方、ご経験のある方いらっしゃいましたら教えていただければ幸いです。

Aベストアンサー

No.2です。
素人ですし、正直詳しくないので、経験談しか語れません。すみません。
やはり、その症状からするとテープが伸びたり痛んだりしているのだと思います。

>2年前まではきちんと見れていたのですが、やはり年月が経ってしまったのでテープの調子が悪くなってしまったのでしょうか?

2年前のしまう直前までは、間違い無く、全て綺麗に見えたのでしょうか?
同じ箇所が少しでもおかしくなかったですか?
2年も経てば保存状態によってはだいぶ痛みますし、色んな症状が出ると思いますが、特定の箇所だけおかしくなるというのは考え難いです。湿気や光の影響を受ければ全体的に、もしくはもっと広範囲に症状が現れると思うのです。
有り得る?とすれば、その箇所は前から多少痛んでいて、経年劣化で全体的に痛んだが、元々痛んでいたその部分だけ正常に再生するだけの能力以下に落ちてしまった・・・ということではないかと。それか、何かの拍子にその部分だけ手垢が付いてしまったとか。今も見た目は綺麗なんですよね?

世の中には、ビデオテープのカビ取りクリーニングや修復を行っているショップもあるようですが、テープ自体にシワや傷が出来た場合、その部分の修復は無理だと言われているようです。

実際映像を見てもらった方が修復可能か判断しやすいでしょうから、地元近辺でそういったサービスをしているお店が無いか探して見てはどうでしょうか。ネットでもありますが、経験した事が無いのでどこが良いとか分かりませんし、送料もかかるでしょうから、修復不可能となった時の事を考えるとあまりお勧めしたくないというのが本音です。

一応、ググッたものを幾つか載せておきます。
ご自分でも探されて、まともな店かな?と思ったらまず問い合わせてみてはどうでしょうか。

http://homepage2.nifty.com/media-s/index.htm
http://www.geocities.jp/kobeibuki/web_media/index.html
http://ksmmsyk.hp.infoseek.co.jp/

また、デジタル化した後の話しですが、ゴーストやブロックノイズとは違って、私はこのようなノイズを補正する術を知りませんが、私が知らないだけで、多少也ともノイズを軽減する方法が「ひょっとしたら」あるかも知れません。
テープ修復をやれるだけやってみてダメだったら、デジタル化したデータを元に新たに質問すると良いと思います。

No.2です。
素人ですし、正直詳しくないので、経験談しか語れません。すみません。
やはり、その症状からするとテープが伸びたり痛んだりしているのだと思います。

>2年前まではきちんと見れていたのですが、やはり年月が経ってしまったのでテープの調子が悪くなってしまったのでしょうか?

2年前のしまう直前までは、間違い無く、全て綺麗に見えたのでしょうか?
同じ箇所が少しでもおかしくなかったですか?
2年も経てば保存状態によってはだいぶ痛みますし、色んな症状が出ると思いますが、特定の箇...続きを読む

QVC++6.0のプロジェクトをVC++2005Expressで動かしたいがエラーが出まくってしまいます。

VC++6.0のプロジェクトをVC++2005Expressで動かしたいのですが
エラーが出まくってしまいます。
VC++6.0では正常にコンパイル終了するものがexpressだと、

・・・string.h(135) : warning C4003: マクロ '__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX' に指定された実引数の数が少なすぎます。

とか、

・・・string.h(135) : error C2065: '_string' : 定義されていない識別子です。

とか、

・・・string.h(135) : error C2275: '_locale_t' : この型は演算子として使用できません

とかです。string.hなど、触ったこともないのですが、
express用に編集が必要なのでしょうか?

ちなみに PlatformSDK などはインストールして、include,exectable,library ディレクトリなどのパスも通しています。

何か良い方法を教えてください。お願いします。

VC++6.0のプロジェクトをVC++2005Expressで動かしたいのですが
エラーが出まくってしまいます。
VC++6.0では正常にコンパイル終了するものがexpressだと、

・・・string.h(135) : warning C4003: マクロ '__DEFINE_CPP_OVERLOAD_STANDARD_FUNC_0_1_EX' に指定された実引数の数が少なすぎます。

とか、

・・・string.h(135) : error C2065: '_string' : 定義されていない識別子です。

とか、

・・・string.h(135) : error C2275: '_locale_t' : この型は演算子として使用できません

とかです。...続きを読む

Aベストアンサー

私も同様でした。
次のように対処しました。
1.警告気にしないことにする。(警告数は966件)
2.エラーは修正する。
3.ヘッダーファイルがないと言われたときは
  ***.h  を  ***  に変える

 エラー修正は
ネームスペースが原因のものがほそんどでしたので
ofstream ofs を使っていた場合は
その前に
using namespace std;
を書き加える。

設定で

プロジェクト
プロパティー
文字セット

のところは、

マルチバイト文字セットを使用する

にしています。

 以上、エラーは無視します!!

Qビデオのダビングをすると画像が乱れる理由

 普通の番組なら3倍モードで重ね録りを何回か繰り返しても、特に画像が乱れることはありませんが、レンタルビデオとかをダビングすると画像がひどく乱れるのはどうしてなのでしょうか?

Aベストアンサー

レンタルは「コピーガードが入っている」から「ダビングすること自体が犯罪(著作権法違反)」です。

QVC++2005で画面上にGIF画像(透過あり)を表示させたい

VC++2005で画面上にGIF画像(透過あり)を表示させたいのですが、
簡単なサンプルはあるでしょうか?

MFCの概念がいまいちわかっていなく、ごく最近
DDX/DDVとテキストボックスの文字表示がわかった程度です。

画像系は何がわかればよいのでしょうか?

Aベストアンサー

VC2005以降なら
CImageクラスを使えば割と簡単に表示可能ですよ

#include "stdafx.h"
#include <atlimage.h>

void myFunc(CDC* pDC)
{
  CImage img;
  img.load( "GIFのファイルパス" );
  CDC* pDCImg = CDC::Fromhandle( img.GetDC() );
  pDC->BitBlt( 0, 0, img->GetWidth(), img->Getheight(),
    pDCImg, 0, 0, SRCCOPY );
  img.ReleaseDC();
}
といった具合で ...

Q電波障害によるテレビ画像の乱れの対処方法を教えてください!!

電波障害によるテレビ画像の乱れの対処方法を教えてください!!

引越した先の電波状況が悪いらしく、テレビの画像が異常に乱れてしまいます。

フレッツスカパーに加入して、パソコンでテレビを見ようとも思いましたが、
対応地域でなかったらしく、加入できませんでした。

他に何か良い対処方法があれば、是非とも教えてください!!

ちなみに、今すんでいるのはマンションです。

Aベストアンサー

うちは戸建てですが・・
購入時に電波障害地域ですといわれていました。
なので自治体で共同アンテナがありました。
しかしそこには加入せずにケーブルテレビに加入しました。

同じマンションの方はどうされているのでしょう?
やはり一度管理人さんにきいてみるといいと思います。

Q【VC++2005(CLR)】時刻の入出力、計算処理の方法を教えてください。

VC++初心者です。

現在CLRでプロジェクトを作成しており、時刻の処理について悩んでおります。
宜しければ、教えて頂けませんでしょうか。
お手数ですが、よろしくお願いします。
*****やりたいこと(例で紹介します。)******************
・ユーザに「23:00:00」(23時00分00秒の意味)を入力欄1に入力させます。
・ユーザに「02:00:00」(02時00分00秒の意味)を入力欄2に入力させます。
・経過時間「03:00:00」(03時00分00秒の意味)を出力欄1に出力させます。

条件:
・時刻は24時間表記のみです。
・上記例のように日をまたぐことも考慮します。
・入力欄1用に、1つのテキストボックス、または、コンボボックスを使用します。
 (ボックスの種類は指定しません。)
 ただし、時間、分、秒、それぞれ分割されたボックスを使用しないで下さい。
・入力欄2も入力欄1と同様のボックスを指定ます。
*******************************************************

VC++初心者です。

現在CLRでプロジェクトを作成しており、時刻の処理について悩んでおります。
宜しければ、教えて頂けませんでしょうか。
お手数ですが、よろしくお願いします。
*****やりたいこと(例で紹介します。)******************
・ユーザに「23:00:00」(23時00分00秒の意味)を入力欄1に入力させます。
・ユーザに「02:00:00」(02時00分00秒の意味)を入力欄2に入力させます。
・経過時間「03:00:00」(03時00分00秒の意味)を出力欄1に出力させます。

条件:
・時刻は24時間表記のみで...続きを読む

Aベストアンサー

とりあえず
http://oshiete1.goo.ne.jp/qa4865001.html
はどうなったのかレスをつけてください。

入力欄2は必ず入力欄1以上になるのでしょうか?

TimeSpanについて調べてみてください。
ちなみに、C++に限定するとあまりいいWebサイトがないのですが、
VBやC#でも同じ.NET Frameworkのライブラリを使っているので、文法以外は参考になるはずですので、
言語が違うからここのサイトは使えないという風にとらえずに探してい見てください。
(C# TimeSpanと検索すれば十分なほど参考になるWebサイトが見つかるはず)


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング