Get Layer Transparency As a Readable Value

Get Layer Transparency As a Readable Value

richardpangburn
Enthusiast Enthusiast
2,733 Views
11 Replies
Message 1 of 12

Get Layer Transparency As a Readable Value

richardpangburn
Enthusiast
Enthusiast

I am trying to get the transparency of a layer so I can see it's value (0-90) but I'm having a hard time getting that to come out right.

string trans = layerTableRecord.Transparency.ToString();
string trimmedTransparency = trans.TrimStart('(').TrimEnd(')');
int intSetting = Int32.Parse(trimmedTransparency);
byte alpha = (byte)(255 * (100 - intSetting) / 100);
layer.Transparency = intSetting.ToString();

layerTableRecord.Transparency.ToString(); returns an 8 digit number inside of parentheses that I trim and convert into an int. I then pass that integer into the line that creates 'alpha' and gives me a value between 0-255 I believe.

 

In this case layer.Transparency = intSetting.ToString(); returns the 8 digit number.

 

But I don't want it to return the 8 digit number I want it to return the same value which would be seen by a user looking at their layer manager in AutoCAD, a number between 0 and 90.

 

layer.Transparency is a string property on a my LayerModel. It is bound to my UI so I would like to set that string as a value a drafter will implicitly understand.

 

Thanks.

0 Likes
Accepted solutions (1)
2,734 Views
11 Replies
Replies (11)
Message 2 of 12

Ajilal.Vijayan
Advisor
Advisor

convert back the Alpha value

use the Alpha value of Transparency
alphaval = layerTableRecord.Transparency.Alpha
int trans =  transvalue(alphaval)

 private int transvalue(byte trans) {           
     double tr = byte.Parse(trans.ToString());
     return System.Math.Abs( Convert.ToInt16 ((tr / 255) * 100 - 100));
  }

 

0 Likes
Message 3 of 12

richardpangburn
Enthusiast
Enthusiast

Thanks Ajilal. By the way, Drawing Purge is an amazing program! it's saved me about 500,000 hours of busy work over the years.

 

I do have a slight issue with the solution you posted and could use some more help.

 

Have implemented it as such:

 

      byte alphaval = layerTableRecord.Transparency.Alpha;
      int trans = transvalue(alphaval);
      layer.Transparency = trans.ToString();

I had to throw the byte declaration in front of alphaval otherwise VS was telling me it doesn't exist in the context. The error I am now getting occurs on that line. I receive an exception of eInvalidKey when I try to run this code.

 

I've tried the following and I am now getting results, it's just that the numbers are wrong:

 

string trans = layerTableRecord.Transparency.ToString();
string trimmedTransparency = trans.TrimStart('(').TrimEnd(')');
int intSetting = Int32.Parse(trimmedTransparency);
byte alpha = (byte)(255 * (100 - intSetting) / 100);
int readableTrans = transvalue(alpha);
layer.Transparency = readableTrans.ToString();

For example, in AutoCAD Layer1 has transparency of 12, but this code returns a value of 51.

0 Likes
Message 4 of 12

Ajilal.Vijayan
Advisor
Advisor

no need to convert transparency to string.

string trans = layerTableRecord.Transparency.ToString();

you could call the function with alpha value directly.

int readableTrans = transvalue(layerTableRecord.Transparency.Alpha);

 For example, in AutoCAD Layer1 has transparency of 12, but this code returns a value of 51.

I receive an exception of eInvalidKey when I try to run this code.

I will check these and update tomorrow.

-------

Glad to hear that Drawing Purge helped you !! 😍

0 Likes
Message 5 of 12

richardpangburn
Enthusiast
Enthusiast

Thanks Ajilal. I tried passing the layerTableRecord.Transparency.Alpha as you suggested but got another eInvalidKey error. From my previous looks into getting transparency it seemed as though the line: 

byte alpha = (byte)(255 * (100 - intSetting) / 100);

Was necessary to get a usable value out of AutoCADs transparency, but I could be off somewhere. I was hoping Transparency would be as easy as setting a property between 0-90 but no such luck! Thanks for taking the time to look into it.

0 Likes
Message 6 of 12

richardpangburn
Enthusiast
Enthusiast

I wanted to add some additional information. The following code absolutely works to SET the layer transparency to 50:

 

int desiredTransparency = 50;
byte alpha = (byte)(255 * (100 - desiredTransparency) / 100);
//Need to find out how to get desiredTransparency from the getting part of the code instead of setting it myself.
Transparency transparency = new Transparency(alpha);
layerTableRecord.Transparency = transparency;

However I need to actually read the layer transparency from a drawing to get my desiredTransparency value and not the weird 6 digit byte values, or the 3 digit values that are being returned with my original post.

Message 7 of 12

richardpangburn
Enthusiast
Enthusiast

Another update. I have found a way to get the transparency value as it's displayed in AutoCAD.

 

if(layerTableRecord.Transparency.Alpha != 0)
{
  int percentage = (int)(((255 - layerTableRecord.Transparency.Alpha) * 100) / 255);
  layer.Transparency = percentage.ToString();
}
else
{
  layer.Transparency = "0";
}

Of course this has unleashed a new problem. If the layer's transparency is set to 0 in AutoCAD, then accessing it will throw an exception. I can't do my if check because it throws a runtime exception. Something about layerTableRecord.Transparency.Alpha being zero makes it unreadable.

 

I can read any other value between 1-90 but if it's zero I crash out. So i just need help now getting around this issue. Basically if that setting is actually zero I don't want to do anything but say that layer.Transparency = "0"; in this situation.

0 Likes
Message 8 of 12

richardpangburn
Enthusiast
Enthusiast
Accepted solution

OK. I think i have found a solution to my problem in the previous post (sorry for replying to myself 300 times to anyone who might find this annoying). Here is the method to get the layer transparency setting as a readable value:

 

if(layerTableRecord.Transparency.IsByAlpha)
{
 int percentage = (int)(((255 - layerTableRecord.Transparency.Alpha) * 
 100) / 255);
 layer.Transparency = percentage.ToString();
}
else
{
 layer.Transparency = "0";
}

Of course this code depends on IsByAlpha being true. However, since I have never heard of any other way to set the transparency of a layer, and IsByAlpha is working on every layer in my drawing, I am prepared to accept this as good enough.

 

I'll wait a while to see if anyone else has input but if not I'll mark this as the solution later.

 

Thank you so much Ajilal for getting me on the right track.

Message 9 of 12

Ajilal.Vijayan
Advisor
Advisor

It seems that checking 'IsByAlpha' is the correct way to avoid the 'eInvalidKey' error.

So I think your solution seems working. 👍

Not sure whether the below affects your program.

You may need to check the MdiActiveDocument.Database.Cetransparency.IsByLayer value

If this transparency is not by layer, then this will override the layer transparency value

 

0 Likes
Message 10 of 12

jhoward-HOB
Contributor
Contributor

It seems to be everywhere so I really don't know the origin of this 255 myth, but by my calculations 250 is the magic number to (exactly) match the AutoCAD layer dialog.

 

I have not tested this on objects, but I'd be surprised if it's any different. I am sure its probably something like 251-255 carrying special meanings on objects; IE, byblock/bylayer

0 Likes
Message 11 of 12

jhoward-HOB
Contributor
Contributor

Not quite sure why I couldn't edit my last one, to fix it.  The 250 did give me a nice clean export from the native layer transparency to my own dialog that lined up without truncating/rounding.

 

However, it doesn't perfectly convert back for lower values, and more importantly, the value can be set to 255 and performing that kind of math would create a negative number... 

0 Likes
Message 12 of 12

jhoward-HOB
Contributor
Contributor

I really couldn't stand an inability to get consistent bidirectional conversions and decided to just map them all into a json file. It wouldn't let me attach json files so I put the txt extension on it.

 

Notes:

  • This usage code assumes the Transparencies.json file was marked as an embedded resource.
  • This was used for layers and you may have to make yourself constants that represent byblock/bylayer for object transparencies.
  • UnPack<> extension method in the code below is a pretty much just doing JsonConvert.DeserializeObject<T>(str);
  • The Key's in the attached are the visual indicators and the values are the byte codes that represent them.

 

public static class Resources
{
    private static Dictionary<int, byte> _transparencies = null;
    private static Dictionary<int, byte> Transparencies { get { return readTransparencies(); } }
    private static Dictionary<int, byte> readTransparencies()
    {
        if (_transparencies == null)
        {
            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
            var resourceName = assembly.FullName.Split(',')[0] + "." + "Transparencies.json";
            using (var stream = assembly.GetManifestResourceStream(resourceName))
            using (var reader = new System.IO.StreamReader(stream))
            { _transparencies = reader.ReadToEnd().UnPack<Dictionary<int, byte>>(); }
        }
        return _transparencies;
    }

    public static int getTransparencyVisualIndex(Autodesk.AutoCAD.DatabaseServices.LayerTableRecord lay)
    {
        if (lay.Transparency.IsInvalid == false && lay.Transparency.IsByAlpha == true)
        {
            int smallestDiff = byte.MaxValue, foundValue = 0;
            foreach (byte key in Transparencies.Keys)
            {
                if (Math.Abs(Transparencies[key] - lay.Transparency.Alpha) < smallestDiff)
                {
                    smallestDiff = Math.Abs(Transparencies[key] - lay.Transparency.Alpha);
                    foundValue = key;
                }
            }
            return foundValue;
        }
        else
            return 0;
    }
    public static Autodesk.AutoCAD.Colors.Transparency getTransparencyValue(int index)
    {
        if (Transparencies.ContainsKey(index) == true)
            return new Autodesk.AutoCAD.Colors.Transparency(Transparencies[index]);
        else
            return new Autodesk.AutoCAD.Colors.Transparency(byte.MaxValue);
    }
}