Page Index Toggle Pages: 1 Send TopicPrint
Hot Topic (More than 10 Replies) clipped png image (Read 4026 times)
brianh
YaBB Newbies
*
Offline



Posts: 30
Joined: Jul 1st, 2008
clipped png image
Jul 3rd, 2008 at 4:37pm
Print Post  
Hi,

I need to implement some 'buttons' on a node, so I used some code I found on this forum to create 'child nodes' (see below), but if I size the button node to match the size of the image it seems to be getting clipped!

Have you any idea what's causing this, is the ShapeNode not a rectangle, or is it rounded (image appears to be rounded at top), or what?

Thanks

Brian

[code]
       virtual protected ShapeNode CreateButton(RectangleF rect, Image img, AttachToNode anchor, ButtonId id)
       {
           // This will create a child node to act as a button

           ShapeNode btn = _diagram.Factory.CreateShapeNode(rect);
           btn.HandlesStyle = MindFusion.Diagramming.HandlesStyle.Invisible;
           btn.Transparent = true;
           btn.Image = img;
           btn.ImageAlign = MindFusion.Drawing.ImageAlign.Center;
           btn.AttachTo(this, anchor);
           btn.Locked = true;
           btn.Visible = true;
           btn.IgnoreLayout = true;
           btn.Tag = id;

           this.SubordinateGroup.AutoDeleteItems = true;
           this.SubordinateGroup.Expandable = true;

           return btn;
       }
[/code]
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: clipped png image
Reply #1 - Jul 3rd, 2008 at 5:25pm
Print Post  
Hi,

What size are you assigning to the node? Note that by default the sizes in the diagram are measured in millimeters, while the Image class' Width and Height properties return pixels. You might use the ClientToDoc method to convert the size in pixels to size in millimeters.

Additionally, set btn.Shape = Shapes.Rectangle, because the shape might be still used as a clip region, event for Transparent nodes.

Stoyan
  
Back to top
 
IP Logged
 
brianh
YaBB Newbies
*
Offline



Posts: 30
Joined: Jul 1st, 2008
Re: clipped png image
Reply #2 - Jul 4th, 2008 at 8:32am
Print Post  
Hi Stoyan,

I was already scaling the image dimensions, and had (I thought) already tried setting the Shape to a rectangle to no avail, but having tried it again this morning it seems to do the trick! Smiley

There is still some clipping to the left hand edge (losing a pixel width from a 13 x 13 pixel image) but by adding 0.1 to each dimension (after converting to document coordinates) that seems to fix the problem.

Thanks for your help.

Brian
  
Back to top
 
IP Logged
 
brianh
YaBB Newbies
*
Offline



Posts: 30
Joined: Jul 1st, 2008
Re: clipped png image
Reply #3 - Jul 4th, 2008 at 9:47am
Print Post  
Hi Stoyan,

Maybe I spoke too soon regarding this new clipping problem.  If I adjust the converted size of the button to cope with the apparent "rounding error" it displays correctly - initially.  But as you drag the parent node about the screen the 'button' will occasionally clip along either the top or left side, presumably because the size is being recalculated as it is moved and depending on it's position on screen it can shrink by a pixel. Sad

I could probably solve this problem by making the button node 1 pixel bigger than the image in each direction, so it would have an invisible 1 pixel border and any moving/resizing would affect this border and leave the image unclipped.

But I also have a 'toolbar' of these 'buttons' displayed in the caption, and these separate by a pixel and then come back together again as I drag the parent node about, so it depends on the nodes postion whether or not the 'toolbar' is in one piece or not. Sad

Is there any way to fix the child node relative to the parent node IN PIXELS so that this doesn't happen?

Thanks.

Brian

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: clipped png image
Reply #4 - Jul 4th, 2008 at 10:56am
Print Post  
Hi Brian,

Flowchart.NET deliberately aligns images to the on-screen pixel boundaries by choosing the integer pixel coordinates closest to the floating-point coordinates of the image. Unfortunately, that leads to the images seemingly changing their distance when displayed on screen.

If an image is not aligned to the physical pixel boundaries, the GDI+ DrawImage method renders it blurred, and we have actually implemented the alignment after customers complained about the smeared image appearance.

You could verify this with a similar code -
Code
Select All
private void button1_Click(object sender, System.EventArgs e)
{
	diagram.DefaultShape = Shapes.Rectangle;
	diagram.ShapeText = "";
	diagram.AlignToGrid = false;
	ShapeNode main = diagram.Factory.CreateShapeNode(0, 0, 100, 100);

	for (int i = 0; i < 3; ++i)
	{
		ShapeNode btn = diagram.Factory.CreateShapeNode(3 + 12*i, 3, 10, 10);
		btn.AttachTo(main, AttachToNode.TopLeft);
		btn.Transparent = true;
		btn.Image = Image.FromFile(@"D:\Images\Icons\all-icons\ac-icons\ac0001\gif\ac0001-32.gif");
		btn.ImageAlign = ImageAlign.Center;
	}

	for (int i = 0; i < 3; ++i)
	{
		ShapeNode btn = diagram.Factory.CreateShapeNode(3 + 12 * i, 15, 10, 10);
		btn.AttachTo(main, AttachToNode.TopLeft);
		btn.CustomDraw = CustomDraw.Full;
	}
}

private void diagram_DrawNode(object sender, DrawNodeEventArgs e)
{
if (!e.Shadow)
{
Image img = Image.FromFile(@"D:\Images\Icons\all-icons\ac-icons\ac0001\gif\ac0001-32.gif");
e.Graphics.DrawImage(img, e.Bounds.X, e.Bounds.Y);
}
}
 



If you run this and move the main node, you will notice that the images on the first row always appear quite sharp, but the distance between them seems to change, while the images on the second row keep their distance, but appear blurred.

One option for you would be to switch MeasureUnit to Pixel, and after any node is modified, round its coordinates to their closest integer values.

Another option is to glue the smaller button images into a single large toolbar image. E.g.you could do that dynamically by creating a Bitmap object, calling Graphics.FromImage(the bitmap), and using Image.Draw to draw the smaller images. Then when you get the NodeClicked event for the toolbar node, check over what part of the large bitmap the mouse cursor is located and act accordingly.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
brianh
YaBB Newbies
*
Offline



Posts: 30
Joined: Jul 1st, 2008
Re: clipped png image
Reply #5 - Jul 4th, 2008 at 12:08pm
Print Post  
Hi Stoyan,

I did consider creating one node for the toolbar but it isn't as 'clean' a solution as using the separate buttons so I would prefer to stay with the buttons if possible.

But in any case, the problem isn't so much that the buttons move, but that they change size! :S

It looks like the left hand edge is being moved to the nearest pixel, but the right hand edge is being calculated independantly (and sometime not being moved) instead of being kept a fixed distance from the left hand edge. :S

I assume that this problem is due to rounding errors when converting betwen pixels and mm, but if the width and height were being converted to pixel counts and added to the left and top pixel positions (instead of converting the actual right and bottom positions from mm to pixels independantly) then they should remain at the same relative pixel positions no matter where they are on the diagram.

Can you confirm that this is what is happening, and is it possible for you to change this behavior as I've suggested in order to keep the nodes a fixed size, or to suggest a way that I could do this instead?

Thanks.

Brian
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: clipped png image
Reply #6 - Jul 4th, 2008 at 12:32pm
Print Post  
Hi Brian,

I haven't noticed the images changing their size in my test, but that could depend on the screen resolution as well. The control honors the DPI stored with an image, so it also multiplies the image size by the image_dpi / screen_dpi value. This usually leads to a floating-point size, which we just pass to DrawImage.

I suppose you might go with the custom-drawing approach, as for the nodes on the second row from my test code above. This will let you use the graphics.DrawImage(image, x, y) method, which should preserve the image size. If you wish to align the image to the screen's pixel boundaries, you can use the alignedDocPos point value -

Point alignedDevPos = Utilities.DocToDevice(graphics, new PointF(x, y));
PointF alignedDocPos = Utilities.DeviceToDoc(graphics, alignedDevPos);

I could not reproduce the images changing their size, but this could depend on the image size and the exact coordinates you are using. If you save your diagram to xml and email the file to support@mindfusion.eu, we can try to improve the built-in pixel alignment.

I hope that helps,
Stoyan
  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: clipped png image
Reply #7 - Jul 4th, 2008 at 12:43pm
Print Post  
- are you actually seeing the image sizes changing, or they are just being clipped? Clipping is done at the exact floating point boundaries of a node, which might get smaller than the image's pixel-aligned coordinates. As a workaround you might use a slightly larger nodes, however depending on the resolution there might be 3-4 pixels in a millimeter, so 0.1mm might not be enough to pass the pixel boundaries - try adding 0.2 or 0.3 to each side.

Stoyan
  
Back to top
 
IP Logged
 
brianh
YaBB Newbies
*
Offline



Posts: 30
Joined: Jul 1st, 2008
Re: clipped png image
Reply #8 - Jul 7th, 2008 at 9:04am
Print Post  
Hi Stoyan,

I modified your code (see below) to make the nodes the same size as the images, and to butt them up to each other (like a toolbar), and although the images were clipped they were consistent (didn't change when I dragged the parent node).

I then changed the AlignToGrid setting to true (which is what I want for the main nodes) and the button images started clipping differently depending on where I dragged the parent node, giving the impression that the buttons are moving! Sad I guess the child nodes are all being aligned to the grid independantly, and so ARE moving in relation to the parent. Sad Is there any way to keep them fixed to the parent and only align the parent to the grid?

Thanks.

Brian

Code
Select All
        private void Test()
        {
            diagram1.DrawNode += new DrawNodeEventHandler(diagram1_DrawNode);
            diagram1.DefaultShape = Shapes.Rectangle;
            diagram1.ShapeText = "";
            diagram1.AlignToGrid = true;// false;
            ShapeNode main = diagram1.Factory.CreateShapeNode(0, 0, 100, 100);

            // image is 16 x 16 pixels
            Size sizButton = new Size(16, 16);

            // get size of toolbar buttons in document coordinates
            Rectangle imgRect = new Rectangle(0, 0, sizButton.Width, sizButton.Height);
            RectangleF buttonRectF = diagramView1.ClientToDoc(imgRect);

            for (int i = 0; i < 3; ++i)
            {
                ShapeNode btn = diagram1.Factory.CreateShapeNode(3 + (buttonRectF.Width * i), 3, buttonRectF.Width, buttonRectF.Height);
                btn.AttachTo(main, AttachToNode.TopLeft);
                //btn.Transparent = false;
                btn.Transparent = true;
                btn.Brush = new MindFusion.Drawing.SolidBrush(Color.Red);
                btn.Image = Properties.Resources.button;// Image.FromFile(@"D:\Images\Icons\all-icons\ac-icons\ac0001\gif\ac0001-32 .gif");
                btn.ImageAlign = ImageAlign.Center;
            }

            for (int i = 0; i < 3; ++i)
            {
                ShapeNode btn = diagram1.Factory.CreateShapeNode(3 + 12 * i, 15, imgRect.Width, imgRect.Height);
                btn.AttachTo(main, AttachToNode.TopLeft);
                btn.CustomDraw = CustomDraw.Full;
            }
        }

        void diagram1_DrawNode(object sender, DrawNodeEventArgs e)
        {
            if (!e.Shadow)
            {
                Image img = Properties.Resources.button;// Image.FromFile(@"D:\Images\Icons\all-icons\ac-icons\ac0001\gif\ac0001-32 .gif");
                e.Graphics.DrawImage(img, e.Bounds.X, e.Bounds.Y);
            }
        }
 

  
Back to top
 
IP Logged
 
Stoyo
God Member
*****
Offline


MindFusion support

Posts: 13230
Joined: Jul 20th, 2005
Re: clipped png image
Reply #9 - Jul 7th, 2008 at 10:24am
Print Post  
Hi Brian,

The child nodes are not aligned to the grid. When the grid is disabled and you drag the main node, the nodes in the group are moved at a distance that is exactly divisible by the pixels size, since the mouse pointer coordinates are always aligned to the screen pixels. So in that case, the images should preserve their relative positions.

When the grid is enabled and you move the nodes, they are offset with a value divisible by GridSize (4 mm by default). Since in the general case it is not multiple of the exact pixel size, the nodes get misaligned from the pixel boundaries. Now when rendering the images, they get aligned to the nearest pixel and appear to not preserve their relative positions.

You might align the grid size to the pixel boundaries too:

RectangleF gridSize = new RectangleF(0, 0, 4, 4);
RectangleF pixelAlignedGridSize = diagramView.ClientToDoc(diagramView.DocToClient(gridSize));
diagram.GridSizeX = pixelAlignedGridSize.Width;
diagram.GridSizeY = pixelAlignedGridSize.Height;

or just set MeasureUnit to Pixel and use an integer grid size.

If you don't mind the images appearing a little blurred, we could add a property that specifies whether they should be rendered at the exact pixel boundaries and spare you all these troubles.

Stoyan
  
Back to top
 
IP Logged
 
brianh
YaBB Newbies
*
Offline



Posts: 30
Joined: Jul 1st, 2008
Re: clipped png image
Reply #10 - Jul 7th, 2008 at 4:17pm
Print Post  
Hi Stoyan,

I decided to go with your suggestion of aligning the grid size to the pixel boundaries, and this seems to have done the trick - although I still needed to adust the button rectangles by 0.1 after converting to document units in order to prevent clipping. :/

Your suggestion of adding a property to specify if the image should be rendered on exact pixel boundaries sounds like a useful option, but in this situation I don't think the blurred images would be acceptable. :/

Thanks for all your help.

Brian
  
Back to top
 
IP Logged
 
Page Index Toggle Pages: 1
Send TopicPrint