CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 3 of 3
  1. #1
    Join Date
    Aug 2001
    Posts
    77

    [RESOLVED] Using TextureBrush for custom Hatch pattern

    Hi all,

    I am trying to draw a custom hatch pattern on some rectangles. I have a 16 color bitmap that contains my desired hatch pattern, drawn in Black and White (White is the background, Black is the actual Hatch pattern), and loaded as an embedded resource. I want to be able to change the colors when I use the bitmap for a TextureBrush to something other than Black and White.

    So, when I create the TextureBrush, I load in the bitmap, then change the first and last colors in the bitmap's palette to, let' say, Red and Yellow. I do this thusly:

    Code:
    public static Image LoadHatchPattern()
    {
    // Load the desired 16 color bitmap ("Hatch1.bmp") from the project's embedded resources (in the 'Textures' folder)
    
       Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Designer.Textures.Hatch1.bmp");
     
    // Create a bitmap from the stream, then change the first and last color (Black & White) to Yellow & Red.
    
       Bitmap b = new Bitmap(s);
       ColorPalette p = b.Palette;
     
       p.Entries[0] = Color.Red;
       p.Entries[15] = Color.Yellow;
     
       b.Palette = p;
     
       //b.MakeTransparent(Color.White);
       return b;
    }

    Here's the problem. If I use the returned Image object to create a TextureBrush, and then use that brush in a call to FillRectangle, the hatch color is still Black and White, not Red and Yellow like I want it to be!

    Here's how I am doing it:

    Code:
    public override void Draw(Graphics g)
    {
       Image image = Support.LoadHatchPattern();
     
    // Test draw the converted bitmap as a bitmap.  This works (draws in Yellow & Red)!
    
       g.DrawImage(Support.LoadHatchPattern(1), SX-10, SY-10);
     
    // Draw a filled rectangle using the SAME BITMAP for the brush.  This doesn't work (fills in Black & White)!
    
       TextureBrush b = new TextureBrush(Support.LoadHatchPattern(1));
       g.FillRectangle(b, SX + 2, SY + 2, W - 2, H - 2);
       b.Dispose();
    }
    Notice the comments. If I draw the converted bitmap as an image, it draws properly, in Yellow and Red. But, when I use the SAME BITMAP for a TextureBrush, the rectangle is filled in Black & White!

    I have looked and looked, and have found no solution or explanation for this behavior. Perhaps some guru out there can provide me one?

    P.S. If I uncomment the 'MakeTransparent' call above, the background goes to transparent, but the foreground pixels remain Black.

    ADDITIONAL INFO:

    By the way, when I uncomment the 'MakeTransparent' call above, the bitmap drawn as an image ALSO shows up with the foreground pixels Black! More fodder for the fire!

  2. #2
    Join Date
    Aug 2001
    Posts
    77

    Re: Using TextureBrush for custom Hatch pattern

    I found a solution!

    Apparently the problem stems from using an indexed Bitmap (in my case 4bpp indexed, 16 colors). Changing the palette out works fine for subsequently drawing the Bitmap (using DrawImage), but the TextureBrush doesn't understand (somehow) that the colors have changed.

    So, I changed to a non-indexed Bitmap for my custom hatch pattern bitmaps, and then I go through a loop to change each Black (Argb(0,0,0) pixel to whatever color I want for the foreground, and each White (Argb(255,255,255)) pixel to whatever color I want for the background. Here is the code I use:

    Code:
    public static Image LoadHatchPattern(int index)
    {
       Color color;
       Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("SoftflowDesigner.Textures.Hatch1.bmp");
       Bitmap b = new Bitmap(s);
    
       for (int x = 0; x < b.Width; x++)
       {
          for (int y = 0; y < b.Height; y++)
          {
             color = b.GetPixel(x, y);
             if      (clr == Color.FromArgb(0,0,0))       b.SetPixel(x, y, Color.Red);
             else if (clr == Color.FromArgb(255,255,255)) b.SetPixel(x, y, Color.Yellow);
          }
       }
    
       return b;
    }
    Since my hatch pattern bitmaps are small (8x8), this is plenty fast enough.

    I then use the returned image for the TextureBrush and it works!

  3. #3
    Join Date
    Aug 2001
    Posts
    77

    Re: Using TextureBrush for custom Hatch pattern

    Update: A better solution!

    I continued to work on this problem, and now I have found a way to use the original bitmaps. In fact, since I am only dealing with a hatch pattern (2 colors), I can change the bitmaps to 2 color mode (PixelFormat.Format1bppIndexed)!

    All it requires is to change the palette information to use the new color(s), then lock the bitmap into memory, then unlock it again. Here is a modified example:

    Code:
          public static Image LoadHatchPattern(int index, Color foreground)
          {
    // Create a bitmap from an embedded resource bitmap file.
             Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream("Designer.Textures.Hatch1.bmp");
             Bitmap b = new Bitmap(s);
     
    // Change out the first color (Black in the original Black & White bitmap) in the palette
             ColorPalette pal = b.Palette;
             pal.Entries[0] = foreground;
             b.Palette = pal;
     
    // Lock and then unlock the bitmap data
             BitmapData data = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat);
             b.UnlockBits(data);
     
    // Make the background color transparent
             b.MakeTransparent();
     
             return b;
          }
    This works exactly the way I want it to, and now I can use B&W 2 color bitmaps, which are much smaller!

    NOTE: I could pass the background color to this function, then add the line below to change out the background color as well. If I do this, I would then remove the call to "b.MakeTransparent()", since I am specifying the background color.


    Code:
    pal.Entries[1] = background;

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured