Wing Posted August 7, 2007 Posted August 7, 2007 Hi im trying to write a function to split one image into a d2 image array well i got this far public Image[,] SplitImages(Image image, int rows, int columns) { Image[,] images = new Image[rows, columns]; for (int row = 0; row < rows; row++) { for (int colum = 0; colum < columns; colum++) { images[row, colum] = new Bitmap(image.Width/rows,image.Height/columns); Graphics g = Graphics.FromImage(images[row, colum]); g.DrawImageUnscaled(image, (image.Width / rows) * row, (image.Height / columns) * colum, (image.Width / rows), (image.Height / columns)); } } return images; } But only the first([0,0]) image in the array works the rest of them just turn blank i dont get why or if i did do any thing wrong.. Tnx for any help you can offer!! Quote
MrPaul Posted August 8, 2007 Posted August 8, 2007 DrawImage One important thing you are failing to do is to dispose of your Graphics object. A using block will handle this for you: using (Graphics g = Graphics.FromImage(images[row, colum])) { //Use g } As for your image problem, the second and third parameters of the DrawImageUnscaled method are the destination coordinates, so you'd need them to be zero. Unfortunately this method does not take source coordinates, so I recommend using DrawImage instead: g.DrawImage( image, //Source image 0, //Dest x 0, //Dest y new Rectangle( (image.Width / rows) * row, (image.Height / columns) * colum, (image.Width / rows), (image.Height / columns) ), //Src rect GraphicsUnit.Pixel //Units ); Good luck :cool: Quote Never trouble another for what you can do for yourself.
Wing Posted August 8, 2007 Author Posted August 8, 2007 (edited) Re: DrawImage Tnx alot looks like it works!!, but its extremely slow is there any way to speed it up? I found bitblt but i cant get it to work the result is just black.... any way here is my bitblt code: public Image[,] SplitImage(Image image, int rows, int columns) { Image[,] images = new Image[rows, columns]; for (int row = 0; row < rows; row++) { for (int colum = 0; colum < columns; colum++) { //UnManaged way using (Graphics sourceG = Graphics.FromImage(image)) { int width = image.Width / rows; int height = image.Height / columns; // get te hDC of the target IntPtr hdcSrc = sourceG.GetHdc(); // create a device context we can copy to IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc); // create a bitmap we can copy it to, // using GetDeviceCaps to get the width/height IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height); // select the bitmap object IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap); // bitblt over GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, width * row, height * colum, GDI32.SRCCOPY); // restore selection GDI32.SelectObject(hdcDest, hOld); // clean up GDI32.DeleteDC(hdcDest); sourceG.ReleaseHdc(hdcSrc); // get a .NET image object for it images[row, colum] = Image.FromHbitmap(hBitmap); // free up the Bitmap object GDI32.DeleteObject(hBitmap); } } } return images; } private class GDI32 { public const int SRCCOPY = 0x00CC0020; // BitBlt dwRop parameter [DllImport("gdi32.dll")] public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource, int nXSrc, int nYSrc, int dwRop); [DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight); [DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleDC(IntPtr hDC); [DllImport("gdi32.dll")] public static extern bool DeleteDC(IntPtr hDC); [DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); [DllImport("gdi32.dll")] public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject); } Edited August 8, 2007 by Wing Quote
Leaders snarfblam Posted August 9, 2007 Leaders Posted August 9, 2007 Re: DrawImage If speed is important then GDI+ is not your friend. Don't get me wrong... I use GDI+ all the time, but when performance is an issue I've resorted to GDI and even (in extreme cases) written my own blitters. From the look of things you seem like you know your way around GDI, so that would be my recommendation. Quote [sIGPIC]e[/sIGPIC]
Wing Posted August 9, 2007 Author Posted August 9, 2007 (edited) Re: DrawImage If speed is important then GDI+ is not your friend. Don't get me wrong... I use GDI+ all the time, but when performance is an issue I've resorted to GDI and even (in extreme cases) written my own blitters. From the look of things you seem like you know your way around GDI, so that would be my recommendation. well that was my first try to use GDI, but as i said it didnt turn out so well when i copy with blitblt the result is black and i still dont know why >.<... Edited August 9, 2007 by Wing Quote
Leaders snarfblam Posted August 10, 2007 Leaders Posted August 10, 2007 Re: DrawImage Oh, I see. Guess I didn't read your last post so well. When you use the Bitmap.GetHdc function, the Hdc is write-only. GDI+ bitmaps can be written to with GDI but not read from. To use GDI you would probably need to load the bitmaps via GDI instead of GDI+. I don't know how to do this since my experience with GDI is mostly limited to VB6 where I could actually use VB to load the bitmaps and then GDI to blit them. Quote [sIGPIC]e[/sIGPIC]
MrPaul Posted August 10, 2007 Posted August 10, 2007 LoadImage function To use GDI you would probably need to load the bitmaps via GDI instead of GDI+. This could be done with LoadImage: [DllImport("user32.dll", EntryPoint="LoadImageW")] public static extern IntPtr LoadImage( IntPtr hInst, [MarshalAs(UnmanagedType.LPWStr)] string lpszName, uint uType, int cxDesired, int cyDesired, uint fuLoad ); public const int IMAGE_BITMAP = 0; public const int LR_LOADFROMFILE = 0x10; For hInst you would pass IntPtr.Zero for loading from a file. uType is IMAGE_BITMAP, and cxDesired and cyDesired can both be passed as zero to use the actual image dimensions. For fuLoad, pass LR_LOADFROMFILE. The returned IntPtr is a hBitmap, so remember to use CloseHandle. Good luck :cool: Quote Never trouble another for what you can do for yourself.
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.