Ah, I'm clearly not familiar with how the array type was implemented. The first member of the buffer_info() tuple is an IntPtr, so you probably want the [IntPtr, int, IntPtr, int] overload of Marshal.Copy. In fact, if you use the buffer_info() approach, you may be able to avoid manually specifying the overload. (Though there's something to be said for the types as a form of documentation -- particularly given the opacity of the call to buffer_info()).
Personally, my rule of thumb is to use the Python standard library for portable and "mostly Pythonic" code, but to use .NET types when doing "mostly .NET". In this case, I think I would have created an Array[Byte] instead of an array('B') as it's a bit more self-documenting. On Sun, Jun 13, 2010 at 3:51 PM, Marcel <marcel.vandendun...@gmail.com>wrote: > Hi Curt, > > Your suggestion gives me: > TypeError: expected Array[Byte], got array > > bytes is a Python array. I tried: > Marshal.Copy.Overloads[Array[Byte], int, IntPtr, int] > (bytes.buffer_info()[0], 0, bmData.Scan0, total_bytes) > > but that gave the error: > TypeError: expected Array[Byte], got int > > This small sample application demonstrates the issue: > > import array > import struct > import StringIO > > import clr > clr.AddReference("System.Windows.Forms") > clr.AddReference("System.Drawing") > > from System import Array, Byte, Char, IntPtr > from System.Windows.Forms import Application, Form, PictureBox > from System.Drawing import Size, Point, Bitmap, Color, Rectangle > from System.Drawing.Imaging import PixelFormat, ImageLockMode > from System.Runtime.InteropServices import Marshal > > class IForm(Form): > > def __init__(self): > bytes = array.array('B') > > width = 25 > height = 20 > > for i in range(width * height): > bytes.append(i % 256) # R > bytes.append(i % 256) # G > bytes.append(i % 256) # B > > bitmap = Bitmap(width, height, PixelFormat.Format24bppRgb) > > bmData = bitmap.LockBits(Rectangle(0, 0, bitmap.Width, > bitmap.Height), > ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb) > > total_bytes = (bmData.Stride) * bmData.Height > > Marshal.Copy.Overloads[Array[Byte], int, IntPtr, int]( > bytes.buffer_info()[0], 0, bmData.Scan0, total_bytes) > bitmap.UnlockBits(bmData) > > ## for x in range(width): > ## for y in range(height): > ## i = y * width + x > ## bitmap.SetPixel(x, y, Color.FromArgb(bytes[i], > bytes[i+1], bytes[i+2])) > > pb = PictureBox() > pb.Size = Size(bitmap.Width, bitmap.Height) > pb.Location = Point(2, 2) > pb.Image = bitmap > pb.Parent = self > > self.Size = Size(bitmap.Width + 20, bitmap.Height + 45) > self.CenterToScreen() > > Application.Run(IForm()) > > Using bitmap.SetPixel works, but I cannot find how to make it work > using the LockBits and Marshal.Copy. > > Thanks, > -- Marcel > > On Jun 12, 10:27 pm, Curt Hagenlocher <c...@hagenlocher.org> wrote: > > It looks like the automatic overload resolution may be failing -- at > least, > > it's worth trying to resolve the overload manually. This would be > something > > like > > > > from System import Array, Byte, IntPtr > > Marshal.Copy.Overloads[Array[Byte], int, IntPtr, int](bytes, 0, > > bmData.Scan0, total_bytes) > > > > On Sat, Jun 12, 2010 at 10:07 PM, Marcel <marcel.vandendun...@gmail.com > >wrote: > > > > > I think I simplified my example a little too far. I'm trying to > > > display a Bitmap from bytes generated in Python code. > > > > > bytes = array.array('c') # tried 'B' also > > > # generate bitmap bytes ... > > > > > bitmap = Bitmap(width, height, PixelFormat.Format24bppRgb) > > > > > bmData = bitmap.LockBits(Rectangle(0, 0, bitmap.Width, > > > bitmap.Height), > > > ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb) > > > > > total_bytes = (bmData.Stride) * bmData.Height > > > > > Marshal.Copy(bytes, 0, bmData.Scan0, total_bytes); > > > > > bitmap.UnlockBits(bmData) > > > > > The IronPython exception I'm getting is: > > > TypeError: expected IntPtr, got array > > > > > Casting the bytes array to IntPtr changed the error into: > > > TypeError: expected int, got array > > > > > I'm using IronPython 2.6 (2.6.10920.0) on .NET 2.0.50727.4927 > > > > > Any idea? > > > > > Thanks, > > > -- Marcel > > > > > On Jun 11, 11:27 pm, David Escobar <davidesco...@ieee.org> wrote: > > > > This worked for me (based on the code you provided): > > > > > > import clr > > > > from System import Array > > > > > > dest = Array[str](bytes) > > > > > > On Fri, Jun 11, 2010 at 9:51 PM, Marcel < > marcel.vandendun...@gmail.com > > > >wrote: > > > > > > > I have a python method that returns a Python byte array.array('c'). > > > > > > > Now, I want to copy this array using > > > > > System.Runtime.InteropServices.Marshal.Copy. This method however > > > > > expects a .NET Array. > > > > > > > import array > > > > > from System.Runtime.InteropServices import Marshal > > > > > > > bytes = array.array('c') > > > > > bytes.append('a') > > > > > bytes.append('b') > > > > > bytes.append('c') > > > > > Marshal.Copy(bytes, dest, 0, 3) > > > > > > > Is there a way to make this work without copying the data? If not, > how > > > > > do I convert the data in the Python array to the .NET array? > > > > > > > Thanks, > > > > > -- Marcel > > > > > _______________________________________________ > > > > > Users mailing list > > > > > us...@lists.ironpython.com > > > > >http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > > > > > _______________________________________________ > > > > Users mailing list > > > > us...@lists.ironpython.comhttp:// > > > lists.ironpython.com/listinfo.cgi/users-ironpython.com > > > _______________________________________________ > > > Users mailing list > > > us...@lists.ironpython.com > > >http://lists.ironpython.com/listinfo.cgi/users-ironpython.com > > > > > > > > _______________________________________________ > > Users mailing list > > us...@lists.ironpython.comhttp:// > lists.ironpython.com/listinfo.cgi/users-ironpython.com > _______________________________________________ > Users mailing list > Users@lists.ironpython.com > http://lists.ironpython.com/listinfo.cgi/users-ironpython.com >
_______________________________________________ Users mailing list Users@lists.ironpython.com http://lists.ironpython.com/listinfo.cgi/users-ironpython.com