Ambilight

  • VB.NET

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von Tsuyo.

    Hallo,
    Ich habe mir in den Kopf gesetzt, zu versuchen "Ambilight" ganz einfach nachzubauen...einfach nur das Video in der Bildschirmmitte, und neber dem Video je links und rechts ne Picturebox, die die passende Farbe annimmt. Hätte gedacht ich nehme einfach einige Pixel am Rand und errechne daraus die Durchschnitts-Farbe (geht sowas überhaupt ?), die die Picturebox dann annehmen soll (Für den Anfang geht auch ein einzelner Pixel, soll sich aber später schon nach mehreren Pixeln richten). Später kann man das evtl. noch via Microcontroller und LED's nützlich verwenden. Soweit die Idee. Kann man sowas überhaupt realisieren ? Ich müsste ja jedes Einzelbild des Videos analysieren...Gibt es überhaupt eine Möglichkeit die Farbe eines bestimmten Pixels / durchschnitt mehrerer Pixel bei jedem Einzelbild zu erkennen und dann die Picturebox anzupassen ? Dann müsste die Picturebox ja auch 24 bzw. 30 mal pro Sekunde ihre Farbe ändern können...Hat jemand eine Idee ? :)
    „Was daraus gefolgert werden kann ist, dass jeder intelligentere User sein Geld lieber für Bier ausgibt, um einen schönen Rausch zu haben, und nicht dieses Ranzprodukt.“

    -Auszug aus einer Unterhaltung über das iPhone und dessen Vermarktung.
    Danke, das mit dem addieren klingt eigentlich logisch... ;)
    Nur wie kann ich denn jedes einzelne Frame eines Films ohne große Verzögerung analysieren ? Ich denke nicht, dass das mit der Mediaplayer-control funktioniert. Ist sowas überhaupt realisierbar ?

    der_Kurt schrieb:



    Mein Problem ist, ich will das Ganze ja nicht einfarbig. Beim Original-Ambilight ists ja auch so wenn oben blau und unten grün ist, dass die Beleuchtung auch 2farbig wird und nciht alles blau bzw. grün. Ich bin gerade dabei das erstmal an einer Picturebox auszuprobieren. Habe vor 4 Farben zu machen (links oben, links unten, rechts oben, rechts unten). Sieht bis jetzt schon mal ganz gut aus...

    Mit dem Vorschlag von Samus Aran werde ich mich mal genauer auseinandersetzen, danke !
    Dann musst du den Bereich eben in Reihen aufteilen. In Abständen von 4 oder 8 Pixeln jeweils die Farbe errechnen und für diesen Bereich setzen. (Das ist jetzt relativ theoretisch gedacht)
    „Was daraus gefolgert werden kann ist, dass jeder intelligentere User sein Geld lieber für Bier ausgibt, um einen schönen Rausch zu haben, und nicht dieses Ranzprodukt.“

    -Auszug aus einer Unterhaltung über das iPhone und dessen Vermarktung.
    Ich würde das per DirectX machen!
    SlimDX z.b kann dir sehr schnell einen 'Screenshot' eines Fensters machen das halt DX benutzt. Es gab ne Klasse von nem Spazzarama oderso. Die hatte ich Abgeändert, ist sehr sehr alter Code und man wird es aufjedenfall noch Optimieren können. Allein, dass das Device immer neu erstellt wird, macht das ganze schon wieder schlecht. Musste umschreiben, ist eh C#


    Spoiler anzeigen

    Quellcode

    1. using System;
    2. using System.Collections.Generic;
    3. using System.Text;
    4. using System.Drawing;
    5. using System.Runtime.InteropServices;
    6. using SlimDX.Direct3D9;
    7. using SlimDX;
    8. using System.Linq;
    9. namespace Spazzarama.ScreenCapture
    10. {
    11. public static class Direct3DCapture
    12. {
    13. private static SlimDX.Direct3D9.Direct3D _direct3D9 = new SlimDX.Direct3D9.Direct3D();
    14. private static Dictionary<IntPtr, SlimDX.Direct3D9.Device> _direct3DDeviceCache = new Dictionary<IntPtr, SlimDX.Direct3D9.Device>();
    15. public static Bitmap bitmap = null;
    16. public static IntPtr hWnd = IntPtr.Zero;
    17. public static SlimDX.Direct3D9.AdapterInformation adapterInfo = _direct3D9.Adapters.DefaultAdapter;
    18. public static SlimDX.Direct3D9.Device device;
    19. public static string f;
    20. public static unsafe Color CaptureRegionDirect3D(IntPtr handle, Rectangle region)
    21. {
    22. hWnd = handle;
    23. #region Get Direct3D Device
    24. if (_direct3DDeviceCache.ContainsKey(hWnd))
    25. {
    26. device = _direct3DDeviceCache[hWnd];
    27. }
    28. else
    29. {
    30. SlimDX.Direct3D9.PresentParameters parameters = new SlimDX.Direct3D9.PresentParameters();
    31. parameters.BackBufferFormat = adapterInfo.CurrentDisplayMode.Format;
    32. Rectangle clientRect = NativeMethods.GetAbsoluteClientRect(hWnd);
    33. parameters.BackBufferHeight = clientRect.Height;
    34. parameters.BackBufferWidth = clientRect.Width;
    35. parameters.Multisample = SlimDX.Direct3D9.MultisampleType.None;
    36. parameters.SwapEffect = SlimDX.Direct3D9.SwapEffect.Discard;
    37. parameters.DeviceWindowHandle = hWnd;
    38. parameters.PresentationInterval = SlimDX.Direct3D9.PresentInterval.Default;
    39. parameters.FullScreenRefreshRateInHertz = 0;
    40. try
    41. {
    42. device = new SlimDX.Direct3D9.Device(_direct3D9, adapterInfo.Adapter, SlimDX.Direct3D9.DeviceType.Hardware, hWnd, SlimDX.Direct3D9.CreateFlags.SoftwareVertexProcessing, parameters);
    43. _direct3DDeviceCache.Add(hWnd, device);
    44. }
    45. catch (SlimDX.Direct3D9.Direct3D9Exception ex) {
    46. f = ex.Message;
    47. }
    48. }
    49. #endregion
    50. using (SlimDX.Direct3D9.Surface surface = SlimDX.Direct3D9.Surface.CreateOffscreenPlain(device, adapterInfo.CurrentDisplayMode.Width, adapterInfo.CurrentDisplayMode.Height, SlimDX.Direct3D9.Format.A8R8G8B8, SlimDX.Direct3D9.Pool.SystemMemory))
    51. {
    52. device.GetFrontBufferData(0, surface);
    53. SlimDX.DataStream dat = surface.LockRectangle(region ,SlimDX.Direct3D9.LockFlags.None).Data;
    54. SlimDX.Direct3D9.SurfaceDescription desc;
    55. desc = surface.Description;
    56. /*SlimDX.Direct3D9.Texture textureCopy = new SlimDX.Direct3D9.Texture(device, desc.Width, desc.Height, 1, 0, desc.Format, SlimDX.Direct3D9.Pool.Managed);
    57. Surface dst = textureCopy.GetSurfaceLevel(0);
    58. Surface src = surface;
    59. Surface.FromSurface(dst, src, Filter.None, 0);
    60. desc = surface.Description;
    61. DataStream d = dst.LockRectangle(new Rectangle(0, 0, desc.Width, desc.Height), LockFlags.None).Data; */
    62. List<Color> l = new List<Color>();
    63. int* p = (int *)dat.DataPointer.ToPointer();
    64. for (int i = 0; i < desc.Width; i++) {
    65. int* ptr2 = (int*)((byte*)p);
    66. l.Add(Color.FromArgb(*ptr2));
    67. }
    68. // var query = l.GroupBy(item => item).OrderByDescending(g => g.Count()).Select(g => g.Key).First();
    69. var query = (from item in l
    70. group item by item into g
    71. orderby g.Count() descending
    72. select new { Item = g.Key, Count = g.Count() }).First();
    73. //int* ptr2 = (int*)((byte*)p);
    74. return (Color)query.Item ;
    75. }
    76. }
    77. }
    78. public struct ColorType
    79. {
    80. public byte b;
    81. public byte g;
    82. public byte r;
    83. public byte a;
    84. public ColorType(byte r, byte g, byte b)
    85. {
    86. this.r = r;
    87. this.g = g;
    88. this.b = b;
    89. this.a = 255;
    90. }
    91. public ColorType(Color c)
    92. {
    93. this.r = c.R;
    94. this.g = c.G;
    95. this.b = c.B;
    96. this.a = c.A;
    97. }
    98. }
    99. #region Native Win32 Interop
    100. /// <summary>
    101. /// The RECT structure defines the coordinates of the upper-left and lower-right corners of a rectangle.
    102. /// </summary>
    103. [Serializable, StructLayout(LayoutKind.Sequential)]
    104. internal struct RECT
    105. {
    106. public int Left;
    107. public int Top;
    108. public int Right;
    109. public int Bottom;
    110. public RECT(int left, int top, int right, int bottom)
    111. {
    112. this.Left = left;
    113. this.Top = top;
    114. this.Right = right;
    115. this.Bottom = bottom;
    116. }
    117. public Rectangle AsRectangle
    118. {
    119. get
    120. {
    121. return new Rectangle(this.Left, this.Top, this.Right - this.Left, this.Bottom - this.Top);
    122. }
    123. }
    124. public static RECT FromXYWH(int x, int y, int width, int height)
    125. {
    126. return new RECT(x, y, x + width, y + height);
    127. }
    128. public static RECT FromRectangle(Rectangle rect)
    129. {
    130. return new RECT(rect.Left, rect.Top, rect.Right, rect.Bottom);
    131. }
    132. }
    133. [System.Security.SuppressUnmanagedCodeSecurity()]
    134. internal sealed class NativeMethods
    135. {
    136. [DllImport("user32.dll")]
    137. internal static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
    138. [DllImport("user32.dll")]
    139. [return: MarshalAs(UnmanagedType.Bool)]
    140. internal static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
    141. /// <summary>
    142. /// Get a windows client rectangle in a .NET structure
    143. /// </summary>
    144. /// <param name="hwnd">The window handle to look up</param>
    145. /// <returns>The rectangle</returns>
    146. internal static Rectangle GetClientRect(IntPtr hwnd)
    147. {
    148. RECT rect = new RECT();
    149. GetClientRect(hwnd, out rect);
    150. return rect.AsRectangle;
    151. }
    152. /// <summary>
    153. /// Get a windows rectangle in a .NET structure
    154. /// </summary>
    155. /// <param name="hwnd">The window handle to look up</param>
    156. /// <returns>The rectangle</returns>
    157. internal static Rectangle GetWindowRect(IntPtr hwnd)
    158. {
    159. RECT rect = new RECT();
    160. GetWindowRect(hwnd, out rect);
    161. return rect.AsRectangle;
    162. }
    163. internal static Rectangle GetAbsoluteClientRect(IntPtr hWnd)
    164. {
    165. Rectangle windowRect = NativeMethods.GetWindowRect(hWnd);
    166. Rectangle clientRect = NativeMethods.GetClientRect(hWnd);
    167. // This gives us the width of the left, right and bottom chrome - we can then determine the top height
    168. int chromeWidth = (int)((windowRect.Width - clientRect.Width) / 2);
    169. return new Rectangle(new Point(windowRect.X + chromeWidth, windowRect.Y + (windowRect.Height - clientRect.Height - chromeWidth)), clientRect.Size);
    170. }
    171. }
    172. #endregion
    173. }