Global Mapper v25.0

C# Get and Set RasterDisplayOptions

alstewart
alstewart Global Mapper User
edited October 2009 in SDK
Hi,

I'm trying to implement GM_GetRasterDisplayOptions and GM_GetRasterDisplayOptions in C#. I've wrapped up the calls and the GM_RasterDisplayOptions_t structure. However when I try something like:

rasterOptions.mTransparent = 1;
rasterOptions.mTranslucency = 55;

The resulting image is not transparent, it becomes dark (almost black) with few pixels turning full white. It almost looks like the image is being clipped. Any ideas what could be wrong?

My DLL calls:
[DllImport(DLLFileName, EntryPoint = "GM_SetRasterDisplayOptions")]
public static extern GM_Error_t32
GM_SetRasterDisplayOptions
(
GM_LayerHandle_t32 aLayer, // in: layer to set options for
ref GM_RasterDisplayOptions_t aOptions // in: display options for raster layer
);

[DllImport(DLLFileName, EntryPoint = "GM_GetRasterDisplayOptions")]
public static unsafe extern GM_Error_t32
GM_GetRasterDisplayOptions
(
GM_LayerHandle_t32 aLayer,
IntPtr aOptions // out: display options for raster layer
);

Comments

  • global_mapper
    global_mapper Administrator
    edited October 2009
    What is your background color? Your translucency value is very low (0 is completely transparent and 255 is opaque), so 55 is nearly completely transparent.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • alstewart
    alstewart Global Mapper User
    edited October 2009
    I realize the value is very low. I actually have the "value" mapped to a a slider control. Sliding from right to left results in the unexpected output.

    This is the image at the 512 end of the scale:
    normalb.jpg

    This is the image on the 0 end of the scale, I would expect it to be "clear" not black as it is, also the background color is Color.Beige

    darkgh.jpg


    Is there anything special I need to do in the C# side of things to get this working? Currently Im writing the image data to a Bitmap, then using that in a picture box.
    What is your background color? Your translucency value is very low (0 is completely transparent and 255 is opaque), so 55 is nearly completely transparent.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • global_mapper
    global_mapper Administrator
    edited October 2009
    Are you seetting the background color to beige using GM_SetBackgroundColor? It looks like it is black.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • alstewart
    alstewart Global Mapper User
    edited October 2009
    No its beige, I've uploaded two new screenshots at higher resolution so you can see better. The first one below you can see the white pixels I mentioned (or I guess there beige) as well as the "dark" to the image.

    darkp.jpg

    Slightly further down the range in the 0-33 values I get something like below. You can see that the back is beige in this shot.. but its almost like the image channels are getting cropped (however checking the values of my raster options shows the RGB max and mins are correct at 255 and 0, and the auto collar is 0)....

    lined.png
  • global_mapper
    global_mapper Administrator
    edited October 2009
    It sounds like perhaps the GM_RasterDisplayOptions_t structure is incorrect. Can you provide me with your structure declaration and how you are setting it up?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • alstewart
    alstewart Global Mapper User
    edited October 2009
    I saw in the header file it was packed to an 8 byte bound. I got tired of fighting C# so I declared is explicit:

    [StructLayout(LayoutKind.Explicit, Size = 64)]
    public struct GM_RasterDisplayOptions_t
    {
    [FieldOffset(0)]
    public UInt32 mSize; // Size of structure

    [FieldOffset(4)]
    public GM_ContrastMode_t8 mContrastMode; // Contrast adjustment mode

    [FieldOffset(5)]
    public Byte mAutoClipCollar; // Automatically crop off a DRG, BSB, or other known collar boundary

    [FieldOffset(6)]
    public Byte mColorIntensity; // Color intensity (0-20). Lower values are lighter, higher values are darker.
    [FieldOffset(7)]
    public Byte mInterpolatePixels; // Smooth pixels by using bilinear interpolation.
    [FieldOffset(8)]
    public Byte mTextureMap; // Texture map this raster layer over any underlying elevation layers.

    // Translucent/transparency support
    [FieldOffset(10)]
    public UInt16 mTranslucency; // Translucency level of layer (0 - completely see-through, 512 - completely opaque)
    [FieldOffset(12)]
    public byte mTransparent; // Is layer transparent?
    [FieldOffset(16)]
    public ulong mTransparentColor; // Color to make transparent
    [FieldOffset(20)]
    public byte mTransparentColorDist; // Fuzzy transparency support. Distance from transparent color to treat nearby colors transparent.

    // Color channel adjustment
    [FieldOffset(21)]
    public SByte mRedAdjustPercent; // Percentage to adjust red color channel by (-100 to 100)
    [FieldOffset(22)]
    public SByte mGreenAdjustPercent; // Percentage to adjust red color channel by (-100 to 100)
    [FieldOffset(23)]
    public SByte mBlueAdjustPercent; // Percentage to adjust red color channel by (-100 to 100)

    // Color band layout support
    [FieldOffset(24)]
    public Byte mBandLayoutValid; // Are the band layout values valid?
    [FieldOffset(25)]
    public Byte mBandIdxRed; // Index of color band (0-based) to use for red color channel
    [FieldOffset(26)]
    public Byte mBandIdxGreen; // Index of color band (0-based) to use for green color channel
    [FieldOffset(27)]
    public Byte mBandIdxBlue; // Index of color band (0-based) to use for blue color channel

    // Contrast adjustment parameters
    [FieldOffset(32)]
    public double mContrastNumStdDev; // Number of standard deviations from mean to stretch for contrast adjustment (if 0 is used the default of 2 will be used)
    [FieldOffset(40)]
    public Byte mContrastShared; // Is the contrast adjustment shared with other loaded layers?

    // Color Grade options
    [FieldOffset(41)]
    public Byte mColorGradeValid; // Are the color grade options valid?
    [FieldOffset(42)]
    public Byte mColorGradeRedInMin; // Minimum red input color value
    [FieldOffset(43)]
    public Byte mColorGradeRedInMax; // Maximum red input color value
    [FieldOffset(44)]
    public Byte mColorGradeRedOutMin; // Minimum red output color value
    [FieldOffset(45)]
    public Byte mColorGradeRedOutMax; // Maximum red output color value
    [FieldOffset(46)]
    public Byte mColorGradeBlueInMin; // Minimum Blue input color value
    [FieldOffset(47)]
    public Byte mColorGradeBlueInMax; // Maximum Blue input color value
    [FieldOffset(48)]
    public Byte mColorGradeBlueOutMin; // Minimum Blue output color value
    [FieldOffset(49)]
    public Byte mColorGradeBlueOutMax; // Maximum Blue output color value
    [FieldOffset(50)]
    public Byte mColorGradeGreenInMin; // Minimum Green input color value
    [FieldOffset(51)]
    public Byte mColorGradeGreenInMax; // Maximum Green input color value
    [FieldOffset(52)]
    public Byte mColorGradeGreenOutMin; // Minimum Green output color value
    [FieldOffset(53)]
    public Byte mColorGradeGreenOutMax; // Maximum Green output color value
    [FieldOffset(56)]
    public float mColorGradeSaturation; // Saturation (valid 0.0 - 1.0)
    };




    /****************************************************/

    The calling code:

    GlobalMapperDLL.GM_RasterDisplayOptions_t rasterOptions = new GlobalMapperDLL.GM_RasterDisplayOptions_t();
    Color c = Color.FromArgb(224, 224, 224);
    GlobalMapperDLL.GM_SetBackgroundColor(c.ToArgb());

    System.Collections.IEnumerator myEnum = LayerHandles.GetEnumerator();
    myEnum.MoveNext();


    GlobalMapperDLL.GM_Error_t32 theErrCode = 0;

    int temp = Marshal.SizeOf(rasterOptions);
    rasterOptions.mSize = (uint)temp;


    IntPtr dPtr = Marshal.AllocHGlobal(temp);
    theErrCode = GlobalMapperDLL.GM_GetRasterDisplayOptions((IntPtr)myEnum.Current, dPtr);
    rasterOptions = (GlobalMapperDLL.GM_RasterDisplayOptions_t)Marshal.PtrToStructure(dPtr, typeof(GlobalMapperDLL.GM_RasterDisplayOptions_t));

    Marshal.FreeHGlobal(dPtr);

    rasterOptions.mTransparent = 1;
    rasterOptions.mTranslucency = (ushort)hScrollBar1.Value;
    rasterOptions.mTransparentColor = 0xffffff;

    //IntPtr tempPtr = MarshalToPointer(rasterOptions);
    theErrCode = GlobalMapperDLL.GM_SetRasterDisplayOptions((IntPtr)myEnum.Current, ref rasterOptions);

    Looking at raster options, it always comes out correct (ie the values I expect)... I've been comparing with the vc++ sample project doing a similar task with an IDC_Slider.
  • global_mapper
    global_mapper Administrator
    edited October 2009
    I don't see any obvious errors, but what does the rasterOptions structure look like after you call GM_GetRasterDisplayOptions? If something looked screwy there that would indicate a likely problem in the declaration.

    Also, why don't you just pass the GM_RasterDisplayOptions_t structure by reference in the GM_GetRasterDisplayOptions and GM_SetRasterDisplayOptions functions rather than using an IntPtr and dealing with all of the marshalling stuff?

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com
  • alstewart
    alstewart Global Mapper User
    edited October 2009
    I tried the marshaling stuff at the beginning before I realized the struct was byte packed. So no reason in particular at this point. I just tried using the ref call syntax and got the same results. As for your other question, this is the state of raster options after a get raster options call (see below). I can also confirm that after I set transparency and and translucency that the values "return" with subsequent calls to get raster options. In other words, it works exactly as it should. The only thing that fails, is the the fact the image turns black like it does. Could it have something to do with how the image is being rendered? The program I'm doing this in is the GM C# sample which is using GM_DrawLayer to render out the images, while the C++ sample is using GM_DrawLayerList...

    Thoughts?

    rasteroptions.jpg
  • alstewart
    alstewart Global Mapper User
    edited October 2009
    Think I got it,

    Changing this:

    LastGMError = GlobalMapperDLL.GM_DrawLayer(Hdc, LayerPtr, ref CurrentViewRect, 0, 0, BackGroundBitmap.Width, BackGroundBitmap.Height);

    To the below, seems to have fixed it, I now have a nice pretty transparent layer.

    LastGMError = GlobalMapperDLL.GM_DrawLayerList(Hdc,
    LayerPtr,
    0,
    GlobalMapperDLL.GM_DrawFlags_t32.GM_DrawFlags_IncrementalRender | GlobalMapperDLL.GM_DrawFlags_t32.GM_DrawFlags_EraseBackground,
    ref CurrentViewRect,
    0,
    0,
    BackGroundBitmap.Width,
    BackGroundBitmap.Height);
  • global_mapper
    global_mapper Administrator
    edited October 2009
    Ah, the erase background flag I think is the key. The translucency takes the color from the layer and blends it with the color behind it from the device context that you are rendering to. If you don't pass the erase background flag it is assumed that you already have other data there or have erased the background yourself (or maybe an earlier GM_DrawLayer call did it), so it just gets blended with whatever was already there (likely black in this case).

    Let me know if I can be of further assistance.

    Thanks,

    Mike
    Global Mapper Support
    support@globalmapper.com