1

this thread is almost what I need: Creating a GraphicsPath from a semi-transparent bitmap

but he is drawing an outline AROUND the image - I need to draw one just a couple of pixels INSIDE the image. basically I'm trying to draw a "Focus Rectangle" (except it's not a rectangle) the result needs to be in the form of a GraphicsPath so i can fit it right into my current code.

private function GetImagePath(img as Image) as GraphicsPath ... end function

[EDIT] ok, first of all i cant even get the code from the other post to work. i keep getting index out of range at this line:

*byte alpha = originalBytes[y * bitmapData.Stride + 4 * x + 3];*

that's IF it even gets past the other stuff first. alot of times it comes out of the first loop having not found a non-transparent point - when most of the image is non-transparent.

the newst problem is that it creates a list of point that dont make any sense. the image is 68x68 my list of points has points like 290x21 and even crazier ones like 2316x-15

this is my original image:

[wont let me upload cause im new]

its the background image of a button that is 70x70 - if that matters at all.

Community
  • 1
  • 1
JeZteR
  • 17
  • 1
  • 6

1 Answers1

1

I would think to use the routine provided in the link, get the output from it, and add your own wrapper around it modifying the path pushing it in the couple pixels you want. You could even make the amount of pixels to move in an input parameter so that you can play around with it.

Else you could add the second pass directly into the routine provided. Either way I think this is a 2 pass approach. You need to find the outer bounds of the object, that is what is provided. Then you need to essentially move around the path yourself, understand the derivative of the path so that you can move your path in perpendicularly to the derivative at the current point you are looking at. You will also have to recognize inside from outside (i.e. which direction to move the line).

An Algorithm might look something like this (remember just algorithm):

Create New List of Points for the new line

For all points i in 0 to (n-2) (points in original point list)
    // Get a New point in between
    float xNew = (x(i) + x(i + 1) ) / 2
    float yNew = (y(i) + y(i + 1) ) / 2

    // Need to figure out how much to move in X and in Y for each (pixel) move along
    // the perpendicular slope line, remember a^2 + b^2 = c^2, we have a and b
    float a = y(i + 1) - y(i)
    float b = x(i + 1) - x(i)
    float c = sqrt( (a * a) + (b * b) )

    // c being the hypotenus is always larger than a and b.
    // Lets Unitize the a and b elements
    a = a / c
    b = b / c

    // Assume the original point array is given in clockwise fashion
    a = -a
    b = -b

    // Even though a was calculated for diff of y, and b was calculated for diff of x
    // the new x is calculated using a and new y with b as this is what gives us the
    // perpendicular slope versus the slope of the given line
    xNew = xNew + a * amountPixelsToMoveLine
    yNew = yNew + b * amountPixelsToMoveLine

    // Integerize the point
    int xListAdd = (int)xNew
    int yListAdd = (int)yNew

    // Add the new point to the list
    AddPointToNewPointList(xListAdd, yListAdd)

Delete the old point list

Image of the geometry I am performing: Image of the Geometry I am algorithmically describing above

trumpetlicks
  • 7,033
  • 2
  • 19
  • 33
  • wow - out of my league. I'll just leave it not drawing the focus. it'll be fine that way. Thanks for your time. – JeZteR May 30 '12 at 19:35
  • i've edited the original post with a bit more detail as to where i'm at on this – JeZteR May 31 '12 at 14:48
  • Did you also un-accept my answer? This answer is correct, I am trying NOT to repeat what was in the other answer. If that code doesn't work, then down vote those answers. I will continue to help. My guess up above is that somehow the image type is not being read correctly. You might try checking the image size after you have opened and read it in. Try from a debugging perspective, printing out the RGBA values from each pixel also printing out their XY coordinates so that you can figure out what is going wrong with their algorithm. – trumpetlicks May 31 '12 at 15:36
  • i'm not that smart. i cant do algebra so i cant write code to do it either. thanks for your help. i've actually ended up finding a completely different way of doing this. im not drawing on the image at all. and as for this answer being correct - if you say so ;) i cant understand it well enough to know the difference. – JeZteR May 31 '12 at 15:47
  • I'd be interested to hear about your solution to your problem :-) – trumpetlicks May 31 '12 at 15:49
  • well, the custom button this image is on already draws its own focus rectangle based on the shape of the button(the button has a curve property that allows it to be drawn rounded). and all of our images will be either rounded rectangles or complete circles. so i just increased the curve value to make the button match the shape of the image then the focus rectangle is drawn on the button inside the border of the image/button. this obviously would never work for the rubber ducky image - but we would never have an image like that. – JeZteR May 31 '12 at 16:21
  • this also means the button and the image have to be the same size. 68x68 in this particular case. – JeZteR May 31 '12 at 16:24
  • actually it doesn't, i just changed the code back to use the button size instead of the image size, then the image can be whatever size. you do have to use the BackgroundImage and not the Image, however. – JeZteR May 31 '12 at 16:30
  • True, If I had known you were working with a circle or (mathematically) shaped object, I prob would have thought to go that route LOL. I thought you truly had oddly shaped objects :-) – trumpetlicks May 31 '12 at 16:52
  • well, I did want it to handle different shapes, for future uses. we may want to use an arrow some day. you never know. thanks again though. – JeZteR May 31 '12 at 18:17