0

私は低レベルのプログラミングの経験がなく、[StructLayout(LayoutKind.Explicit)] を使用しないためにこのコードが必要です。私のサイトは共有ホスト上で中程度の信頼で実行されています。したがって、このコードがそこにあると実行されません。

更新: これを Octree 内で使用して、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

ネイティブコードおよびメモリとの相互運用は、本質的に安全でない操作です。マーシャルクラスへの呼び出しも失敗します。完全な信頼レベルがない限り、メモリにアクセスしたり、相互運用を実行したりすることはできません。

于 2009-07-08T17:47:39.883 に答える
1

Marshal.PtrToStructure メソッド (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 を 1 バイト順で逆に変換することのようです。
このために、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 に答える