プログラミングの初心者ですが、現在VC++2005のフォームアプリケーションでプログラムについて勉強しています。画像を連続表示するところで、わからなくなってしまったので、みなさんのご指導お願いいたします。
やりたい処理は、取り込んだ画像の色を変化させて、順番に表示したい
処理です。作成したプログラムは下記のようになります。
前略
for(n=0; n<256; n+=20){
for(y=0; y<480; y++){
for(x=0; y<640; x++){
bmp->Setpixel(x, y, Color::FromArgb(n, n, n));
}
}
pictureBox->Image = bmp;
Thread::Sleep(2000);
}
nの値をbmpに入れてから一回表示し、さらにnを足してからbmpに入れて表示するといった流れですが、Sleepを入れても何にも表示されません。
どういったところは不具合なのかをよくわかりません。
ご指導をいただければ感謝致します。どうぞよろしくお願い致します。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
#3さんへ
別に君が書いたサンプルコードに対してコメントしたわけではありませんよ。
あなたもよく理解できていないようですが、質問者のコードでは、描画できません。
表に出てこないだけですが、Invalidate()をコールするとWM_PAINTのメッセージがアプリケーションに対して送られて描画される仕組みは、同じですよ。
No.3
- 回答日時:
こんにちは。
チョッと不足したので補足を。現状では真っ黒なビットマップをSetPixel()で着色しているだけなので、黒→白になるだけですので、ファイルから開いたビットマップの場合は、元の色彩を取って計算しないといけません。
後、xボタンを押した時、スレッドが存在していれば止めるためにClosingイベントを追加しています。その他の細かい事は任意でお願いします。
・このコードでは、アプリケーションがWM_PAINTを処理できないので描画できません。
描画出来ています。
ピクチャボックスのImageプロパティにグラフィックをセットしてInvalidate()を呼ぶとピクチャボックスの表示が更新されます。
通常、C++/CLIにWM_PAINTなんてものは出て来ません。
WndProcメソッドをオーバーライドして、WM_PAINTを引っ掛ける事は出来る様に成っていますが、余程の理由でもない限り、行いません。
処理する場合、PlatformSDK側のAPIや構造体を使用する為にwindows.hをインクルードしなければいけない必要性が発生する事がありますが、C++/CLIでは通常使用出来ない様に成っています。
ピクチャボックスにグラフィックスをセットして反映させるだけなら、Paintイベントをオーバーライドする必要はありません。
・まず、Windowsにおける描画の仕組みを理解しましょう。
揚げ足を取る前に、マネージドとアンマネージドの違い位は見抜きましょう。
#pragma once
namespace laylay {
using namespace System;
using namespace System::ComponentModel;
using namespace System::Collections;
using namespace System::Windows::Forms;
using namespace System::Data;
using namespace System::Drawing;
/// <summary>
/// Form1 の概要
///
/// 警告: このクラスの名前を変更する場合、このクラスが依存するすべての .resx ファイルに関連付けられた
/// マネージ リソース コンパイラ ツールに対して 'Resource File Name' プロパティを
/// 変更する必要があります。この変更を行わないと、
/// デザイナと、このフォームに関連付けられたローカライズ済みリソースとが、
/// 正しく相互に利用できなくなります。
/// </summary>
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: ここにコンストラクタ コードを追加します
//
}
protected:
/// <summary>
/// 使用中のリソースをすべてクリーンアップします。
/// </summary>
~Form1()
{
if (components)
{
delete components;
}
}
private: System::Windows::Forms::Button^ button1;
protected:
private: System::Windows::Forms::PictureBox^ pictureBox1;
private:
/// <summary>
/// 必要なデザイナ変数です。
/// </summary>
System::ComponentModel::Container ^components;
#pragma region Windows Form Designer generated code
/// <summary>
/// デザイナ サポートに必要なメソッドです。このメソッドの内容を
/// コード エディタで変更しないでください。
/// </summary>
void InitializeComponent(void)
{
this->button1 = (gcnew System::Windows::Forms::Button());
this->pictureBox1 = (gcnew System::Windows::Forms::PictureBox());
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this->pictureBox1))->BeginInit();
this->SuspendLayout();
//
// button1
//
this->button1->Location = System::Drawing::Point(64, 238);
this->button1->Name = L"button1";
this->button1->Size = System::Drawing::Size(75, 23);
this->button1->TabIndex = 0;
this->button1->Text = L"button1";
this->button1->UseVisualStyleBackColor = true;
this->button1->Click += gcnew System::EventHandler(this, &Form1::button1_Click);
//
// pictureBox1
//
this->pictureBox1->Location = System::Drawing::Point(13, 13);
this->pictureBox1->Name = L"pictureBox1";
this->pictureBox1->Size = System::Drawing::Size(257, 179);
this->pictureBox1->TabIndex = 1;
this->pictureBox1->TabStop = false;
//
// Form1
//
this->AutoScaleDimensions = System::Drawing::SizeF(6, 12);
this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;
this->ClientSize = System::Drawing::Size(292, 273);
this->Controls->Add(this->pictureBox1);
this->Controls->Add(this->button1);
this->Name = L"Form1";
this->Text = L"Form1";
this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);
(cli::safe_cast<System::ComponentModel::ISupportInitialize^ >(this->pictureBox1))->EndInit();
this->ResumeLayout(false);
}
#pragma endregion
//メンバ変数
private: delegate System::Void DelegateSetPixel(System::Int32 n);
private: DelegateSetPixel^ setPixel;
private: System::Threading::Thread^ thread;
private: System::Drawing::Bitmap^ bitmap;
//下ごしらえ
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
//ファイルから読む
System::Drawing::Bitmap^ bmpFromFile = dynamic_cast<System::Drawing::Bitmap^>(gcnew System::Drawing::Bitmap("test.bmp"));
this->bitmap = dynamic_cast<System::Drawing::Bitmap^>(bmpFromFile->Clone());
delete bmpFromFile;
this->pictureBox1->Image = dynamic_cast<System::Drawing::Bitmap^>(this->bitmap->Clone());
this->setPixel = gcnew DelegateSetPixel(this, &Form1::DrawMethod);
this->button1->Tag = gcnew System::Boolean(false);
this->Closing += gcnew System::ComponentModel::CancelEventHandler(this, &Form1::Form1_Closing);
}
//閉じた時
private: System::Void Form1_Closing(System::Object^ sender, System::ComponentModel::CancelEventArgs^ e)
{
if(this->thread != nullptr)
this->thread->Abort();
}
//スレッド中
private: System::Void threadProc()
{
System::Int32 n = 0;
while(*static_cast<System::Boolean^>(this->button1->Tag))
{
this->thread->Sleep(33);
n = System::Math::Min(n + 20, 255);
this->setPixel->Invoke(n);
if(n == 255)n = 0;
}
}
//ボタンを押す
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
System::Boolean% rbRunning = *static_cast<System::Boolean^>(this->button1->Tag);
rbRunning ^= true;
if(rbRunning)
{
this->button1->Text = L"実行中";
this->thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &Form1::threadProc));
this->thread->Start();
}
else
{
this->button1->Text = L"レディ";
this->thread->Abort();
this->thread = nullptr;
}
this->button1->Update();
}
private: System::Void DrawMethod(System::Int32 n)
{
System::Drawing::Bitmap^ bmp = dynamic_cast<System::Drawing::Bitmap^>(this->bitmap->Clone());
for(System::Int32 y = 0; y < bmp->Height; y++)
{
for(System::Int32 x = 0; x < bmp->Width; x++)
{
Color color = bmp->GetPixel(x, y);
System::Int32 R = System::Math::Min(color.R + n, 255);
System::Int32 G = System::Math::Min(color.G + n, 255);
System::Int32 B = System::Math::Min(color.B + n, 255);
bmp->SetPixel(x, y, Color::FromArgb(R, G, B));
}
}
System::Drawing::Image^ image = this->pictureBox1->Image;
this->pictureBox1->Image = bmp;
delete image;
this->pictureBox1->Invalidate();
}
};
}
No.1
- 回答日時:
こんにちは。
Thread::Sleep(2000);の2000が大きすぎて、止まっているのではないでしょうか。33位にしてみては如何でしょうか。
後、SetPixel()は負担の大きいメソッドですので、640x480のイメージを処理するのは実に厳しいと思います。
以下は320x240のイメージ変色をスレッドにて行っていますが、かなり重たいです。pictureBox1とbutton1が必要です。参考程度に。
//メンバ変数
private: delegate System::Void DelegateSetPixel(System::Int32 n);
private: DelegateSetPixel^ setPixel;
private: System::Threading::Thread^ thread;
//下ごしらえ
private: System::Void Form1_Load(System::Object^ sender, System::EventArgs^ e)
{
//ファイルから読むなら
//System::Drawing::Bitmap^ bmpFromFile = dynamic_cast<System::Drawing::Bitmap^>(gcnew System::Drawing::Bitmap("test.bmp"));
//this->pictureBox1->Image = dynamic_cast<System::Drawing::Bitmap^>(bmpFromFile->Clone());
//delete bmpFromFile;
this->setPixel = gcnew DelegateSetPixel(this, &Form1::DrawMethod);
this->pictureBox1->Image = gcnew System::Drawing::Bitmap(320, 240, System::Drawing::Imaging::PixelFormat::Format24bppRgb);
this->button1->Tag = gcnew System::Boolean(false);
}
//スレッド中
private: System::Void threadProc()
{
System::Int32 n = 0;
while(*static_cast<System::Boolean^>(this->button1->Tag))
{
this->thread->Sleep(33);
n = System::Math::Min(n + 20, 255);
this->setPixel->Invoke(n);
if(n == 255)n = 0;
}
}
//ボタンを押す
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{
System::Boolean% rbRunning = *static_cast<System::Boolean^>(this->button1->Tag);
rbRunning ^= true;
if(rbRunning)
{
this->button1->Text = L"実行中";
this->thread = gcnew System::Threading::Thread(gcnew System::Threading::ThreadStart(this, &Form1::threadProc));
this->thread->Start();
}
else
{
this->button1->Text = L"レディ";
}
this->button1->Update();
}
//色彩変化
private: System::Void DrawMethod(System::Int32 n)
{
//ピクチャボックスからイメージを複製
System::Drawing::Bitmap^ bitmap = dynamic_cast<System::Drawing::Bitmap^>(this->pictureBox1->Image->Clone());
//色彩変化
for(System::Int32 y = 0; y < bitmap->Height; y++)
{
for(System::Int32 x = 0; x < bitmap->Width; x++)
{
bitmap->SetPixel(x, y, Color::FromArgb(n, n, n));
}
}
//古いイメージと交換する
System::Drawing::Image^ image = this->pictureBox1->Image;
this->pictureBox1->Image = bitmap;
delete image;
this->pictureBox1->Invalidate();
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) uwscとWinShotを使いスクリーンショットを撮る 1 2022/06/30 21:15
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- Visual Basic(VBA) 【VBA】写真の貼り付けコードがうまく機能しません。 5 2022/09/01 18:43
- Excel(エクセル) エクセル VBA For Next 繰り返しの書き方を教えてください 6 2022/09/01 14:11
- C言語・C++・C# 画像の画素値を変えるC言語のプログラムで指定された画像の中に白い三角形を右上に表示させるにはどのよう 3 2022/10/30 01:16
- Excel(エクセル) EXCELのグラフを画像(JPG形式)で保存、通常実行がうまく行かない。ステップインはうまく行く 3 2022/08/30 12:06
- Excel(エクセル) エクセル、画像ファイル名の書かれたセル(複数個所)に画像を一括で表示させる方法 1 2023/04/19 00:19
- Visual Basic(VBA) エクセルマクロでアニメを作る方法を教えてください。 1 2023/02/07 14:27
- Visual Basic(VBA) エクセルのマクロで対象ごとにシート分けしてその内容をセルに書き込みたい 9 2022/08/24 13:23
- Visual Basic(VBA) ファイル全てを .xlsm に変更したところ、プログラムが途中で落ちてしまっています 17 2022/12/07 12:03
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Androidで画像の中で指定した範...
-
SwingのpaintComponent(...
-
GDI+で描画した画像を消去する...
-
画面のちらつきの原因が知りた...
-
Java、jPanelに描画する
-
getGraphics()の意味を教えて...
-
Canvas等の図形を移動する時,直...
-
C# リストビューの特定のセルの...
-
JAVAでの背景画像表示
-
エクセルVBAで、条件に一致する...
-
「タイプ初期化子が例外をスロ...
-
オブジェクト指向プログラミン...
-
生成したインスタンスを削除す...
-
変数名の付け方
-
servletからjspへオブジェクト...
-
レコード件数の表示
-
複数の変数を宣言する時、同時...
-
private static という変数の修飾
-
インスタンス参照でアクセスで...
-
String.containsの反対機能はあ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VB.NET フォーム上に描いたグ...
-
VB.NETのSendMessageを教えてく...
-
JAVAでの背景画像表示
-
C# DataGridView のCellPaintin...
-
C# リストビューの特定のセルの...
-
重なった要素上でのイベントで...
-
画面のちらつきの原因が知りた...
-
Androidで画像の中で指定した範...
-
複数画像表示切り替え Visual c++
-
Labelコントロールの背景をグラ...
-
VS Treeview のデザイン変更
-
描画処理が実行されない
-
GDI+で描画した画像を消去する...
-
canvasで表示されてる画像を1...
-
このプログラミングをどう組み...
-
ドラッグして矩形を描くには
-
getGraphics()の意味を教えて...
-
DirectXのスプライト機能で3D回転
-
Canvas等の図形を移動する時,直...
-
Exception occurred during eve...
おすすめ情報