GenericParameter : String or image?

Hi
I create a component , to read image.
The first input is generic parameter , i want a solution to check if the type of the input data is a string i use Image.FromFile(input_data) and if it is an image i leave it as it is.

pManager.AddGenericParameter("Bitmap".....

This works fine in c# component but i don’t find the right way to use it in visual studio

  private void RunScript(object x, object y, ref object A)
  {
    try
    {
      Bitmap bmp = (Bitmap) Image.FromFile((string) x);
      A = bmp;
    }
    catch
    {
      Bitmap bmp = x as Bitmap;
      A = bmp;
    }
  }

I try this in visual studio but i get an error when i plug a file string to the input

1. Invalid cast: String » Bitmap

object bmp = null;
Bitmap image;
string data = "";

try
{
    image = (Bitmap)Image.FromFile((string)bmp);
    if (!DA.GetData(0, ref data)) return;
}
catch
{
    image = (Bitmap)bmp;
    if (!DA.GetData(0, ref image)) return;
}

Exceptions originating in catch blocks will throw elsewhere. You really don’t want to do anything risky in a catch block.

Here’s how I’d write it:

Bitmap image = default;
if (value is Bitmap inputBitmap)
  image = inputBitmap;
else if (value is string fileName)
  image = (Bitmap)Image.FromFile(fileName);

You can either use a single try...catch frame around all of it, or put one inside the else block.

1 Like

Thanks @DavidRutten
I tried something like that before but like now i get this error message

1. Solution exception:Object reference not set to an instance of an object.

object bmp = default; // or null the same error

if (!DA.GetData(0 ref bmp)) return;

Bitmap image = default;
if (bmp is Bitmap inputBitmap)
    image = inputBitmap;
else if (bmp is string fileName)
    image = (Bitmap)Image.FromFile(fileName);

CreateSvg(image); //code to create list of points from bitmap (object bmp >> image)

If i use Bitmap bmp to read image or string bmp to read image from file, this work.

A simple component, the output always null.

namespace LoadImage
{
    public class LoadImage : GH_Component
    {

    public LoadImage()
      : base("Image", "Img",
        "Load image",
        "Params", "Util")
    {
    }

    protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager)
    {
        pManager.AddGenericParameter("Image", "I", "", GH_ParamAccess.item);
        pManager[0].Optional = true;
    }

    protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
    {
        pManager.AddGenericParameter("Image", "I", "", GH_ParamAccess.item);
    }


    /// <param name="DA">The DA object can be used to retrieve data from input parameters and 

    protected override void SolveInstance(IGH_DataAccess DA)
    {
        object bmp = default;

        if (!DA.GetData(0, ref bmp)) return;

        Bitmap image = default;

        if (bmp is Bitmap inputBitmap)
            image = inputBitmap;
        else if (bmp is string fileName)
            image = (Bitmap)Image.FromFile(fileName);

        DA.SetData(0, image);
    }

    public override GH_Exposure Exposure => GH_Exposure.primary;

    protected override System.Drawing.Bitmap Icon => null;

    public override Guid ComponentGuid => new Guid("D649643A-DF36-4934-B138-037E9DD8E66A");
    }
}

Have you looked at the actual type and value of bmp in the debugger? What does it say? I’m guessing it might be GH_String or something wrapped like that.

1 Like

Yes i tested with GH_String and it work

object obj = default;

 Bitmap image = default;

 if (!DA.GetData(0, ref obj)) return;

 if (obj is Bitmap inputBitmap)
 {
     image = inputBitmap;
 }
 else if (obj is GH_String fileName)
 {
     image = (Bitmap)Image.FromFile(fileName.Value);
 }

  DA.SetData(0, image);

Update:
I still have a problem with Bitmap, the output always null

I find a solution in Aviary.Macaw.GH code

I add this class and use IGH_Goo instead of object

public static class Extensions
{
    public static bool TryGetBitmap(this IGH_Goo goo, ref Bitmap bitmap)
    {
        bool output = true;

        if (goo.CastTo(out Bitmap bmp))
        {
            bitmap = (Bitmap)bmp.Clone();
        }
        else
        {
            if (goo.CastTo(out Image image))
            {
                bitmap = (Bitmap)image;
            }
            else
            {
                output = false;
            }
        }
        return output;
    }
}

This code work without errors:

Bitmap image;

void CheckBmp(IGH_Goo obj)
{          
    Bitmap bitmap = default;

    if (obj != null)
    {
        Type dataType = obj.GetType();

        if (obj.TryGetBitmap(ref bitmap))
        {
            image = bitmap;
        }
        else if (dataType == typeof(GH_String))
        {
            GH_String ghString = (GH_String)obj;
            image = (Bitmap)Image.FromFile(ghString.Value);
        }
    }
}