m.s.l.f (Mauro Fran&#231&#59;a)

Hi,

I am writing an application which will work like this:

1) Consider an amount of many images, all of these images are aerial images composing a larger image, which is a map of an area.

2)To save speed of processing, these images will be loaded at every 2 images.

3) As these images will be loaded in pairs, I am making a kind of navigator through these 2 images, the images will move from rigth to left, being that the second image fills the space left by the first image, creating an impression of continuity.

4) When the application runs, it is slow, because of the 4 "for(i=0;i<....;i++)" that I created to fill the final image that is displayed to the user ( bitmap temp ).

Does anyone have a suggestion to make it get more faster

Also, if someone detects the need to change the complete principle/philosophy of

the application, I appreciate.

Below is the code for your information

Code Snippet

#pragma endregion

private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)

{

int i,j,k;

Bitmap^ bmp = gcnew Bitmap("C:\\hand.jpg");

Bitmap^ bmp2 = gcnew Bitmap("C:\\hand2.jpg");

Bitmap^ clone1;

Bitmap^ clone2;

int w = bmp->Width;

int h = bmp->Height;

System::Drawing::Rectangle rec(0,0,w,h);

System::Drawing::Rectangle rec2(0,0,w,h);

System::Drawing::Rectangle rec3(0,0,w,h);

Color c;

Bitmap temp = gcnew Bitmap(w,h);

//Moviment of the image, from the right to the left, inside

// a "fixed size window", which is the bitmap variable called temp.

// While bmp moves from rigth to left, bmp2 also moves, creating an

// impression that the first image is continuos.

for ( i = 1; i < w; i++ )

{

rec.X = i;

rec.Width -= 1;

rec2.Width = i;

//Create the half-left image

clone1 = bmp->Clone(rec,bmp->PixelFormat);

//Create the half-rigth image

clone2 = bmp2->Clone(rec2,bmp2->PixelFormat);

//Copy the half-left image to the bitmap temp, temp is fixed size

//i.e, fill temp with the half-left image's pixels

for ( j = 0; j < clone1->Width; j++ )

{

for ( k = 0; k < h; k++)

{

c = clone1->GetPixel(j,k);

temp.SetPixel(j,k,c);

}

}

//Fill the remaining part of bitmap temp with the pixels from

// the half-rigth image

for (j=0; j<clone2->Width;j++)

{

for ( k = 0; k < h; k++)

{

c = clone2->GetPixel(j,k);

temp.SetPixel(j+clone1->Width,k,c);

}

}

Form1::pictureBox1->Image = temp.Clone(rec3,temp.PixelFormat);

Form1::pictureBox1->SizeMode = PictureBoxSizeMode::Normal;

Form1::pictureBox1->Update();

}

}




Re: Visual C++ Express Edition Optimization of my code - support needed.

Principher

I do not know if using unmanaged code is acceptable, if so I would do the following:

1 Call LockBits on the bitmap

2 Get Scan0 from the BitmapData object and call ToPointer(), and save the pointer.

3 Convert the void * to a char *

4 Now use this pointer for writing to the bitmap (see sample for making a white bitmap, I have not compiled it so there may be errors).

Further opmizations are possible, since some of the values are calculated multiple times.

Code Snippet

Bitmap ^bmp = new Bitmap(1024,768, System::Drawing::Imaging::PixelFormat::Format24bppRgb);

BitmapData ^data = bmp->LockBits(...);

char *pOutPixels = (char *)(data->Scan0->ToPointer());

for (int y = 0; y < data->Height; y++) {

for (int x = 0; x < data->Width; x++) {

pOutPixels[((x) * 3) + 0 + ((y) * data->Stride)] = 255;

pOutPixels[((x) * 3) + 1 + ((y) * data->Stride)] = 255;

pOutPixels[((x) * 3) + 2 + ((y) * data->Stride)] = 255;

}

}

bmp->UnlockBits(data);





Re: Visual C++ Express Edition Optimization of my code - support needed.

Mauro Sérgio Lima França

thanks Principher.

But, for the moment I must investigate and read more about the code you posted, regarding these lines:

BitmapData ^data = bmp->LockBits(...);

char *pOutPixels = (char *)(data->Scan0->ToPointer());

.

.

.

pOutPixels[((x) * 3) + 0 + ((y) * data->Stride)] = 255;

Because these are news to me...

Afterwards I can understand properly what is your suggestion. Maybe by tomorrow I can give you a feedback.






Re: Visual C++ Express Edition Optimization of my code - support needed.

nobugz

Don't use Get/SetPixel(), it is brutally slow. Instead, obtain a Graphics instance for "temp" with Graphics::FromImage() and draw the map tiles into it with DrawImage().





Re: Visual C++ Express Edition Optimization of my code - support needed.

Mauro Sérgio Lima França

Princhiper:

I finally understood all the stuff you posted, with the help of the MSDN search ( hundreds of hours later... ) , now when I face LockBits, BitmapData and so on will be familiar, my knowledge about bitmaps handling is only the basics of the basics.

Well, moving towards the approach you suggested ( it seems that it will save runtime ), and as an initial point, I wrote the code below ,this code does as described:

1) Consider an image of size w x h.

2) using the LockBits, the parameter rectangle "rect" will "slide" over the image, creating at every value of "i" a bmpData which represents a portion of the original image. This portion will decrease at every "for" cycle.

3) Question - how do I create a second "System:Big Smilerawing::Imaging::BitmapData^ bmpData2" to receive this block of bits so that they can be displayed on the picture box I tried lots of tricks but unsuccessfull.

Code Snippet

System::Drawing::Imaging::BitmapData^ bmpData;

Rectangle rect = Rectangle(0,0,bmp->Width,bmp->Height);

array<Byte>^rgbValues = gcnew array<Byte>(bytes);

for ( i = 1; i < w; i++ )

{

// Re-sizing the rectangle
rect.X = i;

rect.Width -= 1;

// Locks the bits inside the rectangle ,

bmpData = bmp->LockBits(rect,Imaging::ImageLockMode::ReadWrite,bmp->PixelFormat);

// gets the first address of the block of bits locked

ptr = bmpData->Scan0;

// Re-Calculates the amount of bits locked, it is *3 because of RGB per pixel

bytes = rect.Width*h*3;

// Copy the information regarding the RGB of each pixel to an array called rgbValues, inside this block of bits locked

System::Runtime::InteropServices::Marshal::Copy(ptr, rgbValues,0,bytes);

//Copy these information back to the variable that will be displayed on the picturebox.

System::Runtime::InteropServices::Marshal::Copy(rgbValues,0, ,bytes);

bmp->UnlockBits( bmpData );

Form1::pictureBox1->SizeMode = PictureBoxSizeMode::Normal;

Form1::pictureBox1->Image =

Form1::pictureBox1->Update();

System::Threading::Thread::Sleep(500);

}

thanks again,






Re: Visual C++ Express Edition Optimization of my code - support needed.

Mauro Sérgio Lima França

Hans:

Perfect!

Now it is working fine, smoothly.

Once again thank you very much for the magic tip you gave, helped me a lot!

Thanx also to Principher, who contributed with the LockBit method and other stuff that are necessary to make it work, that

was a valuable contribution.

Take care guys,






Re: Visual C++ Express Edition Optimization of my code - support needed.

ms_syl

Hello,

I would like instancier a power 4(jeu Puissance4) in graphic interface. I would like to thus create in my constructor a dynamic table of 48 pictureBox the three stages are as follows.

Yellow pawn

Red pawn

Empty

My problem is of knowing how to create a dynamic table of 48 pictureBox with Visual studio 2005.

I thank you

My mail: syl_ms@hotmail.com





Re: Visual C++ Express Edition Optimization of my code - support needed.

m.s.l.f (Mauro França)

Hi ms_syl:

Why do you need to create the 48 pictureBoxes You can have an array of 48 images and use on picturebox.

I didn't understand your question clearly, do you have the code you started to write for us to analyse or if you don't , at least a simple explanation of the sequence of calculus the application needs to perform






Re: Visual C++ Express Edition Optimization of my code - support needed.

ms_syl

Power IV is a parlour game which is played has two with the turn has turn the goal etant to make a line of 4 pawns on a grid virticale of 6 lines out of 8 columns of

Here counts it dynamic that I have make in C++. But I would like to do it with the software Visual studio under Windows form application, and in the place of the points I post pictureBox

#include <iostream>

using namespace std;

int **t;

int taille_i;

int taille_j;

void Free_Tab(); // Liberer l'espace memoire;

int main(){

cout<<"Tapez la valeur de taille_i : ";cin>>taille_i;

cout<<"Tapez la valeur de taille_j : ";cin>>taille_j;

/* Allocation dynamique */

t = new int *[taille_i];

for(int i = 0; i < taille_i; ++i)

{

tIdea = new int[taille_j];

}

/* Initialisation */

for(int i = 0; i < taille_i; ++i)

for(int j = 0; j < taille_j; ++j)

tIdea[j]=0;

/* Affichage */

for(int i = 0; i < taille_i; ++i)

{

for(int j = 0; j < taille_j; ++j)

cout<<tIdea[j]<< " ";

cout << endl;

}

return 0;

}

void Free_Tab()

{

for(int i = 0; i < taille_i; ++i)

delete[] tIdea;

delete t;

}

it is my code with Windows form application

#pragma once

#include<stdlib.h>

namespace puissance_4 {

using namespace System;

using namespace System::ComponentModel;

using namespace System::Collections;

using namespace System::Windows::Forms;

using namespace System:Big Smileata;

using namespace System:Big Smilerawing;

/// <summary>

/// Summary for Form1

///

/// WARNING: If you change the name of this class, you will need to change the

/// 'Resource File Name' property for the managed resource compiler tool

/// associated with all .resx files this class depends on. Otherwise,

/// the designers will not be able to interact properly with localized

/// resources associated with this form.

/// </summary>

public ref class Form1 : public System::Windows::Forms::Form

{

public:

Form1(void)

{

InitializeComponent();

//

//TODO: Add the constructor code here

//

table= gcnew System:Big Smilerawing::Rectangle::Inflate(int ligne,int colonne);

for(int i=0;i<5;i++)

{

tableIdea= gcnew PictureBox();

for(int j=0;j<7;j++)

{

table[j]= gcnew PictureBox();

}

tableIdea[j]= gcnew PictureBox();

}

tableIdea[j]=PictureBox();

}

protected:

/// <summary>

/// Clean up any resources being used.

/// </summary>

~Form1()

{

if (components)

{

delete components;

}

}

private:

/// <summary>

/// Required designer variable.

/// </summary>

array<PictureBox^,2>^table= gcnew array<PictureBox^,2>(ligne,colonne);

int ligne;

int colonne;

System::ComponentModel::Container ^components;

#pragma region Windows Form Designer generated code

/// <summary>

/// Required method for Designer support - do not modify

/// the contents of this method with the code editor.

/// </summary>

void InitializeComponent(void)

{

this->SuspendLayout();

//

// Form1

//

this->AutoScaleDimensions = System:Big Smilerawing:Tongue TiedizeF(6, 13);

this->AutoScaleMode = System::Windows::Forms::AutoScaleMode::Font;

this->ClientSize = System:Big Smilerawing:Tongue Tiedize(292, 266);

this->Name = L"Form1";

this->Text = L"Form1";

this->Load += gcnew System::EventHandler(this, &Form1::Form1_Load);

this->ResumeLayout(false);

}

#pragma endregion

private: System::Void Form1_Load(System:Surprisebject^ sender, System::EventArgs^ e)

{

this->Activated->DynamicInvoke(cli::array<PictureBox^,2>^table);

}

};

}