HighTechTalks DotNet Forums  

PictureBox ReSize occurs when assigning Image

Dotnet Framework (Drawing) microsoft.public.dotnet.framework.drawing


Discuss PictureBox ReSize occurs when assigning Image in the Dotnet Framework (Drawing) forum.



Reply
 
Thread Tools Search this Thread Display Modes
  #1  
Old   
Bill Burris
 
Posts: n/a

Default PictureBox ReSize occurs when assigning Image - 01-17-2007 , 02:02 PM






private void pictureBox1_Resize(object sender, EventArgs e)
{
int w = pictureBox1.Width;
int h = pictureBox1.Height;
pictureBox1.BackgroundImage = new Bitmap(w, h);
pictureBox1.Image = new Bitmap(w, h);
Display();
}

In this piece of code a Resize event is triggered again by the line
pictureBox1.Image = new Bitmap(w, h);

Why is this happening, and why does the picture box revert to its
previous size when this occurs.

I have the PictureBox Dock property set to Fill. The PictureBox is on a
Panel which also has its Dock property set to Fill.

I set a breakpoint at the int w line, then hit the maximize button. The
program stops at the break point and I single step. w and h get
assigned values appropriate for my full screen window.
When continuing to single step the assignment to the Image property
causes the Resize event to occur again and single step jumps back to the
int w line. The pictureBox1 Width and Height have reverted back to what
they were before the maximize button was clicked.

When running at full speed (no breakpoint or stepping), the Window is
maximized but the bitmap of the pre maximize size is displayed in the
top corner of the PictureBox area.

Adding the line:

Debug.WriteLine(w.ToString() + " " + h.ToString());

following the assignment to w and h give the following:

1280 822
931 383

Here is my Display function, which sets up for drawing on the bitmap.

private void Display()
{
// reflect about the x axis, to have positive y point up
// and translate y = 0 to bottom of the picture box
Matrix myMatrix = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
pictureBox1.Height);
Graphics g = Graphics.FromImage(pictureBox1.BackgroundImage);
g.Transform = myMatrix;

// translate y = 0 to the bottom of the picture box
graph.Display(new Canvas(g, new Size(pictureBox1.Width,
pictureBox1.Height), this.Font));
}

The reason for using the bitmaps in this manner instead of just drawing
on the PictureBox during a paint event, is so that I can have the 2
layers to draw on. The BackgroundImage display the graph and the Image
displays the rubber band rectangle for mouse selection.

Bill

Reply With Quote
  #2  
Old   
Bob Powell [MVP]
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-17-2007 , 02:18 PM






The picturebox will resize because of the size mode and the fact that an
image created in memory may not be the real resolution of your screen.

An image created in this way will assume 96 DPI but if you're screen is
different, drawing the image will result in a size change.

As to your technique in general, It would be far simpler to draw on an
image and then use the resulting image in the PictureBox.Image property.

For a rubber banded rectangle you can use the PictureBox.Paint,
MouseMove, MouseDown and MouseUp in the classic manner and draw with a
simple alpha-blend pen or, if you really must,
ControlPaint.DrawReversibleXXX.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.





Bill Burris wrote:
Quote:
private void pictureBox1_Resize(object sender, EventArgs e)
{
int w = pictureBox1.Width;
int h = pictureBox1.Height;
pictureBox1.BackgroundImage = new Bitmap(w, h);
pictureBox1.Image = new Bitmap(w, h);
Display();
}

In this piece of code a Resize event is triggered again by the line
pictureBox1.Image = new Bitmap(w, h);

Why is this happening, and why does the picture box revert to its
previous size when this occurs.

I have the PictureBox Dock property set to Fill. The PictureBox is on a
Panel which also has its Dock property set to Fill.

I set a breakpoint at the int w line, then hit the maximize button. The
program stops at the break point and I single step. w and h get
assigned values appropriate for my full screen window.
When continuing to single step the assignment to the Image property
causes the Resize event to occur again and single step jumps back to the
int w line. The pictureBox1 Width and Height have reverted back to what
they were before the maximize button was clicked.

When running at full speed (no breakpoint or stepping), the Window is
maximized but the bitmap of the pre maximize size is displayed in the
top corner of the PictureBox area.

Adding the line:

Debug.WriteLine(w.ToString() + " " + h.ToString());

following the assignment to w and h give the following:

1280 822
931 383

Here is my Display function, which sets up for drawing on the bitmap.

private void Display()
{
// reflect about the x axis, to have positive y point up
// and translate y = 0 to bottom of the picture box
Matrix myMatrix = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
pictureBox1.Height);
Graphics g = Graphics.FromImage(pictureBox1.BackgroundImage);
g.Transform = myMatrix;

// translate y = 0 to the bottom of the picture box
graph.Display(new Canvas(g, new Size(pictureBox1.Width,
pictureBox1.Height), this.Font));
}

The reason for using the bitmaps in this manner instead of just drawing
on the PictureBox during a paint event, is so that I can have the 2
layers to draw on. The BackgroundImage display the graph and the Image
displays the rubber band rectangle for mouse selection.

Bill

Reply With Quote
  #3  
Old   
Bill Burris
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-17-2007 , 04:31 PM



Thanks Bob for setting me on the right track.

The following code works, but if I assign the Bitmap to the Image
instead of the BackgroundImage the rest of the form doesn't display
properly until after I move it with the mouse.

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if ((itsBitmap.Width != pictureBox1.Width) || (itsBitmap.Height !=
pictureBox1.Height))
{
itsBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
GenerateBitmap();
}
pictureBox1.BackgroundImage = itsBitmap;
}

private void GenerateBitmap()
{
// reflect about the x axis, to have positive y point up
// and translate y = 0 to bottom of the bitmap
Matrix myMatrix = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
itsBitmap.Height);
Graphics g = Graphics.FromImage(itsBitmap);
g.Transform = myMatrix;
graph.Display(new Canvas(g, new Size(itsBitmap.Width,
itsBitmap.Height), this.Font));
}

Bill

Reply With Quote
  #4  
Old   
Bob Powell [MVP]
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-18-2007 , 07:57 AM



I'd be disinclined to change the content of an image inside the paint
event. That looks like a race condition waiting to happen.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.





Bill Burris wrote:
Quote:
Thanks Bob for setting me on the right track.

The following code works, but if I assign the Bitmap to the Image
instead of the BackgroundImage the rest of the form doesn't display
properly until after I move it with the mouse.

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
if ((itsBitmap.Width != pictureBox1.Width) || (itsBitmap.Height !=
pictureBox1.Height))
{
itsBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
GenerateBitmap();
}
pictureBox1.BackgroundImage = itsBitmap;
}

private void GenerateBitmap()
{
// reflect about the x axis, to have positive y point up
// and translate y = 0 to bottom of the bitmap
Matrix myMatrix = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
itsBitmap.Height);
Graphics g = Graphics.FromImage(itsBitmap);
g.Transform = myMatrix;
graph.Display(new Canvas(g, new Size(itsBitmap.Width,
itsBitmap.Height), this.Font));
}

Bill

Reply With Quote
  #5  
Old   
Bill Burris
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-18-2007 , 03:56 PM




If I can't change the PictureBox.Image in the Paint or Resize events how
do I know when to update it for window resizing?

Bill

Reply With Quote
  #6  
Old   
Bob Powell [MVP]
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-19-2007 , 02:06 AM



Why do you think you can't change it in the Resize event?
That's what it's for...

The problem is that you have something else that's causing a resize and
its that which is causing the problem.

I've written some test code...

Random r = new Random();

private void pictureBox1_Resize(object sender, EventArgs e)
{
Bitmap bm=new Bitmap(pictureBox1.Width, pictureBox1.Height);
Graphics g=Graphics.FromImage(bm);
g.Clear(Color.FromArgb(r.Next(255),r.Next(255),r.N ext(255)));
pictureBox1.Image = bm;
}

which, if your situation was consistent with mine, would cause the
screen to flash a new colour all the time. In fact it stabilises
immediately which is what I expect.

I also tried the scenario that the bitmap resolution may change the size
but in fact PictureBox is too stupid to use this so it has a saving
grace after-all.

What you describe is a classic race condition. Without seeing all of
your code it will be impossible to say what the problem is and then that
stops being advice and becomes consulting...



--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.





Bill Burris wrote:
Quote:
If I can't change the PictureBox.Image in the Paint or Resize events how
do I know when to update it for window resizing?

Bill

Reply With Quote
  #7  
Old   
Bill Burris
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-19-2007 , 12:15 PM



Bob Powell [MVP] wrote:
Quote:
Why do you think you can't change it in the Resize event?
That's what it's for...
I was going by your original response to my question.

Quote:
The picturebox will resize because of the size mode and the fact that
an image created in memory may not be the real resolution of your screen.

From this it looked like you were telling me that my second resize
event was being caused by the assignment to Image in the Resize event
handler. Therefore I assumed that assigning to Image inside the Resize
event was not a good idea.

What I will do now is put something simple in my Resize event like you
have in your example and see what happens. If all goes well with this,
I will start looking for other things in my code which may be changing
the size of the PictureBox.

Thanks for the advice Bob. I am only taking this thread as far as
anyone wants to go with it. When you have better things to do than give
me free advice, feel free to start ignoring me.

This is for a work project, but my intention is to post the code on my
website. I also plan to fix the resize problem in my Fractal program
which I have posted at:
http://www.componentsnotebook.com/no.../fractals.aspx
I had this problem with resize in that program years ago. Since it
wasn't critical I never got around to solving it. In that case the
Image needs regenerated anyway, and it takes a long time, I just let the
user click the Draw button to change the size of the BackgroundImage.

thanks

Bill

Bill


Reply With Quote
  #8  
Old   
Bill Burris
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-19-2007 , 04:27 PM



I think I found the source of the problem.

In my code I was creating a new bitmap and assigning it to
PictureBox.Image, which would trigger a second Resize event. I don't
know why this was causing it to revert back to the previous size.

If I change the size of the bitmap that was previously assigned and do
not assign to Image again it avoids the second Resize event;

Here is the code which appears to work properly:

private void Form1_Load(object sender, EventArgs e)
{
itsBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
itsSelBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
GenerateBitmap();
pictureBox1.BackgroundImage = itsBitmap;
pictureBox1.Image = itsSelBitmap;
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
}

private void GenerateBitmap()
{
// reflect about the x axis, to have positive y point up
// and translate y = 0 to bottom of the bitmap
Matrix myMatrix = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
itsBitmap.Height);
Graphics g = Graphics.FromImage(itsBitmap);
g.Transform = myMatrix;
graph.Display(new Canvas(g, new Size(itsBitmap.Width,
itsBitmap.Height), this.Font));
}

private void pictureBox1_Resize(object sender, EventArgs e)
{
itsBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
itsSelBitmap = new Bitmap(pictureBox1.Width, pictureBox1.Height);
GenerateBitmap();
pictureBox1.BackgroundImage = itsBitmap;
Debug.WriteLine(pictureBox1.Width + " " + pictureBox1.Height);
}

private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
isMouseDown = true;
itsLastPoint = new Point(e.X, e.Y);
}

private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown)
{
int x, y, width, height;
x = Math.Min(e.X, itsLastPoint.X);
width = Math.Max(e.X, itsLastPoint.X) - x;
y = Math.Min(e.Y, itsLastPoint.Y);
height = Math.Max(e.Y, itsLastPoint.Y) - y;
Rectangle NewSelRect = new Rectangle(x, y, width, height);
DrawSelection(NewSelRect);
}
}

private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown = false;
int x1, y1, x2, y2;
if ((e.X == itsLastPoint.X) && (e.Y == itsLastPoint.Y))
{
double xCenter = pictureBox1.Width / 2;
double yCenter = pictureBox1.Height / 2;
// add code for mouse single click here
}
else
{
//User may have selected from right to left
x1 = Math.Min(e.X, itsLastPoint.X);
x2 = Math.Max(e.X, itsLastPoint.X);
y1 = Math.Min(e.Y, itsLastPoint.Y);
y2 = Math.Max(e.Y, itsLastPoint.Y);
//If tiny selection, assume accidental mouseup
if (Math.Abs(x1 - x2) > 3 && Math.Abs(y1 - y2) > 3)
{
ClearSelection();
ZoomSelection(new Point(x1, y1), new Point(x2, y2));
}
}

private void ZoomSelection(Point p1, Point p2)
{
// reflect about the x axis, to have positive y point up
// and translate y = 0 to the bottom of the picture box
Matrix myMatrix = new Matrix(1.0f, 0.0f, 0.0f, -1.0f, 0.0f,
pictureBox1.Height);
Graphics g = Graphics.FromImage(pictureBox1.BackgroundImage);
g.Transform = myMatrix;

Matrix m = g.Transform;
Point[] points = new Point[2];
points[0] = p1;
points[1] = p2;
m.TransformPoints(points);
graph.Zoom(points[0], points[1]);
GenerateBitmap();
pictureBox1.Refresh();
}

private void DrawSelection(Rectangle ZoomRect)
{
Graphics g = Graphics.FromImage(itsSelBitmap);

ClearSelection(g); // erase prev sel rectangle
Pen pen = new Pen(Color.LightBlue, 2);
pen.DashPattern = new Single[] { 1, 1, 2, 1 };
g.DrawRectangle(pen, ZoomRect);
pictureBox1.Image = itsSelBitmap;
}

private void ClearSelection()
{
Graphics g = Graphics.FromImage(itsSelBitmap);
g.Clear(Color.Transparent);
}

private void ClearSelection(Graphics g)
{
g.Clear(Color.Transparent);
}

The original idea for this code came from a magazine article by Bill
Storage:
http://www.fawcette.com/vsm/2002_08/...ktopdeveloper/
I modified his code to create my Fractal program:
http://www.componentsnotebook.com/no.../fractals.aspx
and have been tweaking it ever since.

Bill

Reply With Quote
  #9  
Old   
Bob Powell [MVP]
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-24-2007 , 02:22 PM



Hi Bill,
Any assignment of an image to the Image property will force a repaint.

Look at the code for the PictureBox with Reflector.

I guess the most useful advice I can give is to study carefully the
intentions of the various events or messages and to ensure that you
respond in context.

For example, don't do something in the Paint handler that causes a
repaint. This will eat processor cycles and slow the program down
enormously.

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.





Bill Burris wrote:
Quote:
Bob Powell [MVP] wrote:
Why do you think you can't change it in the Resize event?
That's what it's for...

I was going by your original response to my question.

The picturebox will resize because of the size mode and the fact that
an image created in memory may not be the real resolution of your screen.

From this it looked like you were telling me that my second resize
event was being caused by the assignment to Image in the Resize event
handler. Therefore I assumed that assigning to Image inside the Resize
event was not a good idea.

What I will do now is put something simple in my Resize event like you
have in your example and see what happens. If all goes well with this,
I will start looking for other things in my code which may be changing
the size of the PictureBox.

Thanks for the advice Bob. I am only taking this thread as far as
anyone wants to go with it. When you have better things to do than give
me free advice, feel free to start ignoring me.

This is for a work project, but my intention is to post the code on my
website. I also plan to fix the resize problem in my Fractal program
which I have posted at:
http://www.componentsnotebook.com/no.../fractals.aspx
I had this problem with resize in that program years ago. Since it
wasn't critical I never got around to solving it. In that case the
Image needs regenerated anyway, and it takes a long time, I just let the
user click the Draw button to change the size of the BackgroundImage.

thanks

Bill

Bill

Reply With Quote
  #10  
Old   
rene vicuna
 
Posts: n/a

Default Re: PictureBox ReSize occurs when assigning Image - 01-26-2007 , 11:38 AM



HI, PLEASURE KNOW ABOUT YOU
ACTUALLY I'VE GOT A LITTLE BIT TROUBLE WITH A TASK I WAS GIVEN,
I'VE PLOT THE KOCH CURVE FRACTAL USING VISUAL BASIC 6 BUT INTO A FORM,
THEN I WOULD LIKE DISPLAY THE KOCH CURVE IN THE PICTUREINBOX, TO SAVE IT
AS A IMAGE.BIP
COULD YOU PLEASE HELP TO ME IN ACHIEVE THIS TASK
DISPLAY THE KOCH CURVE INTO THE PICTUREINBOX

*** Sent via Developersdex http://www.developersdex.com ***

Reply With Quote
Reply




Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off



Powered by vBulletin Version 3.5.4
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.