Request for SetPixel in Form object.

forisco

Member
Licensed User
Please Erel, adds the SetPixel method (to change the color of a pixel) to Form object!!!

The Line method don't works correctly for some applications!

Thank you! :sign0085:
 

forisco

Member
Licensed User
I'm working to my project GraPPC, a graphic program.

For the method FloodFill (fill an area with a color) i need to set the color for a single pixel but with the Line method i have some problems. For example, for this method i must to control the color of the adjacent pixels for any pixel and if i use the Line method i cover this pixels!

This is my work in progress :
 

Attachments

  • FlooFill.zip
    7 KB · Views: 210

forisco

Member
Licensed User
I tryed to use the SetPixel method from the ImageLib library but i have the same problem : two pixel for each point! Why?
This is my code (bmp is a BitMap object):

B4X:
Sub App_Start
   Form1.Show
   bmp.New2(Form1.Width,Form1.Height)

End Sub

Sub Form1_MouseDown (x,y)
      bmp.SetPixel(x,y,cRed)
      Form1.Image = bmp.Value
   
End Sub
 

klaus

Expert
Licensed User
Longtime User
I added a Pen function to your program using the
bmp.SetPixel to show that it works

You needs to add Form1.Refresh
without the refresh function it does not work.

In your case you should copy the bitmap and refresh only after the end of the fill function.

Form1.Line(x,y,x+1,y+1,color) gives a line of two pixels.

Anyway the SetPixel function for the Form would be nice.

Klaus
Switzerland
 

Attachments

  • floogfill_1.zip
    7.5 KB · Views: 201

agraham

Expert
Licensed User
Longtime User
Using your code of SetPixel on a bitmap from ImageLib I too get two pixels. But they are not actually two solid pixels. Looking at them using the Magnifier tool I can see that they are combinations of two or more shaded (not solid colour) pixels. I don't fully understand what is happening here but the reason for this seems to be that although the bitmap is nominally the same size of the form in fact it is not! You can see this by clicking on the right side of the form and noticing that the pixel(s) do not appear under the mouse pointer. The pixels are being stretched in mapping the bitmap onto the form.


You can in fact get a single pixel by adding the BF parameter to Line

Form1.Line(x,y,x+1,y+1,color,BF)

I don't remember having to add this before but maybe my memory is at fault!

EDIT :- Something HAS changed. My FormEx library uses something similar to provide a SetPixel function and it is now broken and produces two pixels? I wonder what has changed?
 
Last edited:

forisco

Member
Licensed User
Klaus, if i use your Pen function in my FloodFill function i receive an error : Windows close the B4PPC with a standard message!!!
And it happen the same thing with the Line method suggested by agraham!!!

For me, the problem is in the memory management of B4PPC. The recoursive method that i use for FloodFill function use a lot of memory. In Visual Basic 6 for Windows i obtain the same result if i use a large area to fill; if i use a small area all works fine.

A question : it's possible to increase the memory used by B4PPC? Or it uses yet the maximum of available RAM memory?

Note : with my code almost all works fine : with a SetPixel function for the Form i'm sure of solve my problem.
 
Last edited:

klaus

Expert
Licensed User
Longtime User
I tested the different possibilities of the line function.
It seems having a somewhat strange behaviour:
Line(x,y,x+1,y+1,color) gives a line of two pixels
Line(x,y,x+1,y+1,color,B) gives a square of four pixels
Line(x,y,x+1,y+1,color,BF) gives a single pixel ?
Attached some examples.

I have found some interesting articles about filling polygons with non recursive methods.

http://www.cs.rit.edu/~icss571/filling/index.html

http://alienryderflex.com/polygon_fill/

I have not yet looked in details, neither tested these methods, but hope they could be helpfull.
I am also looking for a fill method for my IconEdit program.

Klaus
Switzerland
 

Attachments

  • Line.gif
    Line.gif
    8.5 KB · Views: 203

agraham

Expert
Licensed User
Longtime User
It seems having a somewhat strange behaviour:
Line(x,y,x+1,y+1,color) gives a line of two pixels
Line(x,y,x+1,y+1,color,B) gives a square of four pixels
Line(x,y,x+1,y+1,color,BF) gives a single pixel ?
It's not so strange if you know what the underlying .NET functions do.

Line(x1,y1,x2,y2,color) Draws a line from x1,y1 to x2,y2. This is the one whose behaviour seems to have changed for me but it is a .NET change not a B4PPC change as it happens in my FormExDesktop libarary which calls .NET directly. Previously it seemed to draw a line from x1,y1 to x2-1,y2-1 which gave a single pixel. Now it behaves as it is documented "Draws a line connecting two Point structures".

Line(x1,y1,x2,y2,color,B) Draws the single pixel border of a rectangle defined by x1,y1, and x2,y2. So four pixels in the minimum case.

Line(x1,y1,x2,y2,color,BF Fills the INTERIOR of a rectangle defined by x1,y1, and x2,y2. So theoretically 0 pixels in the minimum case but it seems to default to 1 pizel located at x1,y1. Actually it always starts the fill at x1,y1 rather than x1+1,y1+1 so you could argue that it is buggy although it IS documented to behave this way.
 
Last edited:

klaus

Expert
Licensed User
Longtime User
Hello agraham,

It's interesting to know that
Line(x,y,X+1,y+1,color,BF) equals SetPixel(x,y,color)
could this behaviour be added to the help file ?

From a logical point of view, I would have expected the same result with
Line(x,y,x+1,y+1,color,B) equal to Line(x,y,x+1,y+1,color,BF)
because in the first case it's the border with nothing in there
and in the second case the internal square is ZERO, so nothing to fill in but the border remains the same.

But knowing that Line(x,y,x+1,y+1,color,BF) equals SetPixel(x,y,color) it's OK for me.
Additional question: can the border and fill colors be different ?


Hello forisco

The two links in my previous post are for vector graphics with known vertex coordinates, here is one for raster graphics.

http://www.codeproject.com/KB/GDI-plus/queuelinearfloodfill.aspx?df=100&forumid=359235&exp=0&select=1760928

Best regards

Klaus
Switzerland
 
Last edited:

agraham

Expert
Licensed User
Longtime User
Additional question: can the border and fill colors be different ?
No. BF doesn't mean Border and Fill separately it is just a flag to say which actual .NET graphics function is called. Here is the code from my FormExDesktop library to show what I mean. It is in C# but it should be reasonably clear what's happening. Inside Basic4PPC the code will be very similar.

B4X:
public void bLine(int x1, int y1, int x2, int y2, int col, String fmt) 
{
   Rectangle rect = new Rectangle(x1, y1, x2 - x1, y2 - y1);
   switch (fmt.ToLower())
   {
      case "b" :
         PaintGraphics.DrawRectangle(new Pen(Color.FromArgb(col)), rect);
         break;
      case "bf" :
         PaintGraphics.FillRectangle(new SolidBrush(Color.FromArgb(col)), rect);
         break;
      default :
         PaintGraphics.DrawLine(new Pen(Color.FromArgb(col)), x1, y1, x2, y2);
         break;
   }
}
 

klaus

Expert
Licensed User
Longtime User
Hello forisco
Grazie for your link, I had also seen this link but, I don't know why, I was somewhat afraid to use a recursive routine. I implemented the routine in my program and it works fine, with SetPixel. I have only 32*32 pixels so no problem with execution time.

Hello agraham,
Thank's for the complementary information, I had in mind, was it from another language, I don't remember, that B=border and F=fill with two different colors.
But now know that it is not the case.

Best regards and thank's again.

Klaus
Switzerland
 

forisco

Member
Licensed User
In fact, Klaus, my problem is just this : i use, as design space, almost all the screen and b4ppc crash in effort to solve all the recoursions.

I'm studing a different solution. I will inform you about my progresses!

Thank you and ciao!
 

klaus

Expert
Licensed User
Longtime User
I was yesterday a little bit euphoric because the routine worked on the desktop, but on the device I have the same problem as you 'out of stack memory' even with only 32*32 pixels.
I must also look for another routine, as soon as I have found a solution I will of course also inform you.

Grazie e ciao

Klaus
Switzerland
 

agraham

Expert
Licensed User
Longtime User
Here you are. A data stack based non-recursive flood fill routine. It uses two Array List controls StackX and StackY. It is rather slow on the device but it works. I will try to speed it up a bit now I've got it working - in the mean time you can progress with your projects.
 

agraham

Expert
Licensed User
Longtime User
And here's a fast version. I've put the data stack algorithm in a library where I can do manipulation of the bitmap directly. It's very fast now, even on the device.

EDIT :- I should have mentioned that this library needs Compact Framework 2.0 as Compact Framework 1.0 lacks the facility to manipulate bitmaps at a low level.
 

Attachments

  • FastFloodFill.zip
    9.3 KB · Views: 197
Last edited:

klaus

Expert
Licensed User
Longtime User
Hello agraham
Thank you very much for your precious help.

I have implemented the routine, works well.

Unfortunately a have to use the slow version becaus I don't only use bitmap but also a magnified area. On the device it takes about 9s to fill the whole 32*32 square, it's not too bad.

Klaus
Switzerland
 

agraham

Expert
Licensed User
Longtime User
Unfortunately a have to use the slow version becaus I don't only use bitmap but also a magnified area. On the device it takes about 9s to fill the whole 32*32 square, it's not too bad
If I knew how you were implementing the magnified area I might be able to help. Do you want to post some example code?
 
Top