RGB to Grayscale with ShapeDiverImageSampler

Hi everybody,

I am doing a shapediver definition, in which basically from an input image I would like to get the grayscale at locations. The ShapeDiverImageSampler component, returns colors in RGB format.


I am then wondering how to convert these colors in grayscale. I am thinking about splitting the returned list into a tree such that each branch (corresponding to a pixel) contains three items (R, G and B) and then use a formula (like L = 0.2125R + 0.7152G + 0.00722B) to convert the colors into grayscale. But as any shapediver definition should be optimized for speed, I am wonder if there is a faster way.

Thanks in advance.

1 Like

Your method will work, but it might be faster using the attached script. You can modify the formula in the script, it is a little different than the one you wrote above:

grey_scale.gh (4.8 MB)

2 Likes

Adding my C# component that converts a bitmap to either grayscale (with variable contrast) or black/white (with variable threshold). No debugging, no guarantees that this works properly. Use on your own risk :smiley:

EDIT: Modified to work also with transparent PNG.

Will this work correctly in @shapediver environment?

GrayscaleBW.gh (66.9 KB)

  private void RunScript(object B, bool G, double F, ref object BW)
  {
    /*
    author:   Petr Vacek (petrvacek.com)
    date:     24. 10. 2023
    version:  2
    */

    Component.Description = "Converts bitmap image to black/white or grayscale";
    Component.Params.Input[0].Name = "Bitmap";
    Component.Params.Input[0].Description = "Input bitmap image.";
    Component.Params.Input[1].Name = "Grayscale toggle";
    Component.Params.Input[1].Description = "Set false for black/white and true for grayscale output.";
    Component.Params.Input[2].Name = "Factor";
    Component.Params.Input[2].Description = "Factor to influence the result";

    // create array of contrast values for colour matrix
    float[] contrastRow = new float[5];
    // image attributes object
    var imageAtts = new System.Drawing.Imaging.ImageAttributes();

    if (G == true) {
      // let user know which mode is active
      Component.Message = "Grayscale";
      // using F as a contrast factor
      float c = 2 * (float) F - 1;

      contrastRow[0] = c;
      contrastRow[1] = c;
      contrastRow[2] = c;
      contrastRow[3] = 0;
      contrastRow[4] = 1;

    } else {
      // let user know which mode is active
      Component.Message = "Black & White";
      // using F factor as a B/W threshold
      imageAtts.SetThreshold((float) F);

      contrastRow[0] = 0;
      contrastRow[1] = 0;
      contrastRow[2] = 0;
      contrastRow[3] = 0;
      contrastRow[4] = 1;
    }

    var grayscale_matrix = new float[][] {
      new float[] { 0.299f, 0.299f, 0.299f, 0, 0 },
      new float[] { 0.587f, 0.587f, 0.587f, 0, 0 },
      new float[] { 0.114f, 0.114f, 0.114f, 0, 0 },
      new float[] { 0,      0,      0,      1, 0 },
      contrastRow
      };

    imageAtts.SetColorMatrix(new System.Drawing.Imaging.ColorMatrix(grayscale_matrix));

    if (B != null)
    {
      Bitmap inputB = (Bitmap) B;
      Bitmap sourceImage = (Bitmap) inputB.Clone();

      int imgWidth = sourceImage.Width;
      int imgHeight = sourceImage.Height;
      Rectangle rc = new Rectangle(0, 0, imgWidth, imgHeight);

      // empty bitmap
      Bitmap bmp = new Bitmap(imgWidth, imgHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

      using (Graphics g = Graphics.FromImage(bmp))
      {
        g.Clear(Color.White);
        g.DrawImage(sourceImage, rc, 0, 0, imgWidth, imgHeight, GraphicsUnit.Pixel, imageAtts);
      }
      BW = bmp;
    }
  }
2 Likes

This is amazing. Would it be very hard to add transparency to the image, where there is white pixels?
Iā€™m trying to make a logo upload option for a shpadiver definition and am struggling with transparency :frowning:

I managed to edit it with a little bit of research and chatgpt. thanks for the nice script.

bmp.MakeTransparent(Color.White);

1 Like

added option to include specify color to make transparent and a range value
GrayscaleBW.gh (57.5 KB)