0

我没有低级编程经验,我需要这段代码不使用 [StructLayout(LayoutKind.Explicit)]。我的网站在共享主机上运行并处于中等信任状态。因此,如果此代码在那里,它将不会运行。

更新: 我在八叉树中使用它来量化 png 文件。

有谁知道解决方法?

在此处更新 新问题 =>有什么方法可以安全地进行图像量化且无需编组?

/// <summary>
        /// Struct that defines a 32 bpp colour
        /// </summary>
        /// <remarks>
        /// This struct is used to read data from a 32 bits per pixel image
        /// in memory, and is ordered in this manner as this is the way that
        /// the data is layed out in memory
        /// </remarks>
        [StructLayout(LayoutKind.Explicit)]
        public struct Color32
        {

            public Color32(IntPtr pSourcePixel)
            {
                this = (Color32)Marshal.PtrToStructure(pSourcePixel, typeof(Color32));

            }

            /// <summary>
            /// Holds the blue component of the colour
            /// </summary>
            [FieldOffset(0)]
            public byte Blue;
            /// <summary>
            /// Holds the green component of the colour
            /// </summary>
            [FieldOffset(1)]
            public byte Green;
            /// <summary>
            /// Holds the red component of the colour
            /// </summary>
            [FieldOffset(2)]
            public byte Red;
            /// <summary>
            /// Holds the alpha component of the colour
            /// </summary>
            [FieldOffset(3)]
            public byte Alpha;

            /// <summary>
            /// Permits the color32 to be treated as an int32
            /// </summary>
            [FieldOffset(0)]
            public int ARGB;

            /// <summary>
            /// Return the color for this Color32 object
            /// </summary>
            public Color Color
            {
                get { return Color.FromArgb(Alpha, Red, Green, Blue); }
            }
        }
4

3 回答 3

1

与本机代码和内存互操作本质上是不安全的操作。对 Marshal 类的任何调用也会失败。除非您具有完全信任级别,否则您无法访问内存或执行任何互操作。

于 2009-07-08T17:47:39.883 回答
1

Marshal.PtrToStructure Method (IntPtr, Type) 无论如何都不起作用,因为它需要

[SecurityPermissionAttribute(
    SecurityAction.LinkDemand, 
    Flags = SecurityPermissionFlag.UnmanagedCode)]

您可以自己安全地处理偏移量,但您必须在不使用 Marshal 的情况下进行。
为了简单起见,我建议也转向使用 uint。

public struct Color32
{
    const uint BlueMask  = 0xFF000000;       
    const uint GreenMask = 0x00FF0000;
    const uint RedMask   = 0x0000FF00;
    const uint AlphaMask = 0x000000FF;
    const int BlueShift  = 24;       
    const int GreenShift = 16;
    const int RedShift   = 8;
    const int AlphaShift = 0;

    private byte GetComponent(uint mask, int shift)
    {
        var b = (this.ARGB & mask);
        return (byte) (b >> shift);            
    } 

    private void SetComponent(int shift, byte value)
    {
        var b = ((uint)value) << shift
        this.ARGB |= b;
    } 

    public byte Blue 
    {
        get { return GetComponent(BlueMask, BlueShift); }
        set { SetComponent(BlueShift, value); }
    }

    public byte Green
    {
        get { return GetComponent(GreenMask, GreenShift); }
        set { SetComponent(GreenShift, value); }
    }

    public byte Red
    {
        get { return GetComponent(RedMask, RedShift); }
        set { SetComponent(RedShift, value); }
    }

    public byte Alpha
    {
        get { return GetComponent(AlphaMask, AlphaShift); }
        set { SetComponent(AlphaShift, value); }
    }

    /// <summary>
    /// Permits the color32 to be treated as an UInt32
    /// </summary>
    public uint ARGB;

    /// <summary>
    /// Return the color for this Color32 object
    /// </summary>
    public Color Color
    {
        get { return Color.FromArgb(Alpha, Red, Green, Blue); }
    }
}

但是看起来您想要做的是将一个字节顺序的 int32 转换为相反的顺序。
为此,您有System.Net.IPAddress.HostToNetworkOrder(在这方面令人讨厌的用法,您只是使用它来反转字节序,而不是具体说明您打算使用哪种顺序)

因此,如果您可以将输入数据读取为简单的 int32 值,请执行以下操作:

static Color FromBgra(int bgra)
{
    return Color.FromArgb(System.Net.IPAddress.HostToNetworkOrder(bgra));
}

这可能会简单得多。

于 2009-07-08T18:03:48.883 回答
0

您可以只存储 int ARGB,并使用BitConverter将其转换为 4 个字节以返回颜色。

更好的是,只需存储 int,然后使用Color.FromArgb(Int32)

这两种方法都无需存储单个字节,因此您可以完全消除 StructLayout 属性。

于 2009-07-08T17:46:59.463 回答