Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I scale up the hatchstyle drawn in a rectangle? [closed]

I'm using .Net drawing to draw a diagram. It is essentially a stacked bar chart. The issue I have is that I want to reduce the amount of lines in the hatch style so in a way scale it up to make it clearer. I've looked around but didn't come across anything that could help me.

I draw a rectangle and then use a hatchbrush to fill it but due to image size the hatchfill becomes less clearer. Thank you for any suggestions.

The hatchStyles and brush types are stored in the db and I use a helper function to return them. So I draw the rectangle and after getting the brush I fill the rectangle. Essentially I want to scale up the hatch fill if that can be done.

 g.DrawRectangle(gridpen, startX, startY, BOREHOLE_RECT_WIDTH, layerRectHeight);

 brush = GetBoreholeBrush(l.SoilTypeMatrixLevel1Id.PrimaryBrushType,
                          l.SoilTypeMatrixLevel1Id.PrimaryFillStyle, 
                          l.SoilTypeMatrixLevel1Id.PrimaryColour);

 g.FillRectangle(brush, startX, startY, BOREHOLE_RECT_WIDTH, layerRectHeight);

And the getBrush function; the brush type, hatch style and colour are stored in the db and used to create the returned brush:

    //===================================
    private Brush GetBoreholeBrush(string BrushType, string HatchStyle, string Colour)
    //===================================
    {
        //Decide on what brush type has been chosen.
        Brush brush;
        if (BrushType.ToLower() == BrushTypes.HatchBrush.ToString().ToLower())
        {
            brush = new HatchBrush(GetHatchStyle(HatchStyle), 
                                   Color.Black, ColorTranslator.FromHtml(Colour));
        }
        else if (BrushType.ToLower() == BrushTypes.SolidBrush.ToString().ToLower())
        {
            brush = new HatchBrush(GetHatchStyle(HatchStyle), 
                                   Color.Black, ColorTranslator.FromHtml(Colour));
        }
        else if (BrushType.ToLower() == BrushTypes.TextureBrush.ToString().ToLower())
        {
            brush = new HatchBrush(GetHatchStyle(HatchStyle), 
                                   Color.Black, ColorTranslator.FromHtml(Colour));
        }
        else
        {
            brush = new HatchBrush(GetHatchStyle(HatchStyle), 
                                   Color.Black, ColorTranslator.FromHtml(Colour));
        }

        return brush;
    }

Function to return the hatch style:

   //===================================
    private HatchStyle GetHatchStyle(string FillStyle)
    //===================================
    {
        //Loop through each hatch tyle and return the correct one.
        foreach (HatchStyle style in Enum.GetValues(typeof(HatchStyle)))
        {
            if (style.ToString().ToLower() == FillStyle.ToLower())
            {
                return style;
            }
        }
        return HatchStyle.Vertical;
    }

As you can see in the image below the hatch style is not clear.

enter image description here

like image 600
Tony_89 Avatar asked Nov 26 '15 11:11

Tony_89


1 Answers

The most direct but probably not very helpful answer is : No you can't scale the hatch pattern of a HatchBrush.

It is meant to always look sharp at the pixel level and is not even affected by scaling the Graphics object.

Looking at your question I wonder: Are you sure you are really using a HatchBrush? You get the brush from a function GetBoreholeBrush. If you really have stored indices into the 50 HatchStyle then I guess you really use a HatchBrush.

Now as using a HatchBrush won't work I guess you could use a TextureBrush instead..

You could transform the hatch patterns to larger versions by scaling them up; this is not exactly a simple conversion. The direct approach of drawing the larger by an integer factor and without anti-aliasing is simple and may be good enough.

But you may need to fine-tune them, as this way all pixels, that is both line pixels and background pixels get enlarged and also all diagonals will look jagged.

So you would need to balance the hatch size and the stroke width and recreate all patterns you need from scratch in larger sizes.

Here is an example that illustrates the problems with the simple solution; the first row is the original hatch pattern the others are simple texture brush results, scaled by 1x, 2x and 3x..:

enter image description here

First a function to transform a HatchBrush to a TextureBrush

TextureBrush TBrush(HatchBrush HBrush)
{
    using (Bitmap bmp = new Bitmap(8,8))
    using (Graphics G = Graphics.FromImage(bmp))
    {
        G.FillRectangle(HBrush, 0, 0, 8, 8);
        TextureBrush tb = new TextureBrush(bmp);
        return tb;
    }
}

Note that the hatch pattern is 8x8 pixels.

Now the Paint code used for the above image:

private void panel1_Paint(object sender, PaintEventArgs e)
{
    var hs = (HatchStyle[])Enum.GetValues(typeof(HatchStyle));

    for (int i = 0; i < hs.Length; i++)
        using (HatchBrush hbr = new HatchBrush(hs[i], Color.GreenYellow))
        using (HatchBrush hbr2 = new HatchBrush(hs[i], Color.LightCyan))
        {
            e.Graphics.FillRectangle(hbr, new Rectangle(i * 20, 10,16,60));
            using (TextureBrush tbr = TBrush(hbr2))
            {
                e.Graphics.FillRectangle(tbr, new Rectangle(i * 20, 80, 16, 60));
                tbr.ScaleTransform(2, 2);
                e.Graphics.FillRectangle(tbr, new Rectangle(i * 20, 150, 16, 60));
                tbr.ResetTransform();
                tbr.ScaleTransform(3,3);
                e.Graphics.FillRectangle(tbr, new Rectangle(i * 20, 220, 16, 60));
            }
        }
}

Note that while the TextureBrush has nice methods to modify the texture, the HatchBrush has nothing like that at all..

like image 72
TaW Avatar answered Sep 22 '22 17:09

TaW