2009-07-08 52 views
0

我對低級編程沒有經驗,我需要這段代碼才能使用[StructLayout(LayoutKind.Explicit)]。我的網站運行在共享主機和中等信任。 所以它不會運行,如果這個代碼在那裏。將[StructLayout]替換爲不使用System.Runtime.InteropServices的內容?

更新: 我正在使用這個裏面的八叉樹來量化PNG文件。

有沒有人知道工作?

更新 這裏=>Is there any way to do Image Quantization safely and with no Marshalling?

/// <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); } 
      } 
     } 
+0

你想做什麼?你不能只使用`Bitmap`類嗎? – 2009-07-08 17:33:41

+0

您能否介紹一下爲什麼/如何使用非託管代碼? – 2009-07-08 17:34:07

+0

這似乎是他試圖與來自其他來源的數據進行交互,使用不同的字節順序 – ShuggyCoUk 2009-07-08 18:05:09

回答

1

Marshal.PtrToStructure方法(IntPtr的,類型)無論如何都不會工作,但你必須要做到這一點,而無需使用元帥。
爲了簡單起見,我還建議使用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)); 
} 

這可能會簡單得多。

0

你可以只保存INT ARGB,並使用BitConverter將其轉換爲4個字節爲您的色彩還原新問題。

更好的是,只存儲整數,並使用Color.FromArgb(Int32)

這兩種方法都不需要存儲單個字節,因此可以完全消除StructLayout屬性。

1

與本地代碼和內存互操作本質上是不安全的操作。任何對Marshal類的調用都會失敗。除非您擁有完全的信任級別,否則無法訪問內存或執行任何Interop。因爲它需要

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

你可以處理偏移自己安全