Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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!!

Posted

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:

Never trouble another for what you can do for yourself.
Posted (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 by Wing
  • Leaders
Posted

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.

[sIGPIC]e[/sIGPIC]
Posted (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 by Wing
  • Leaders
Posted

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.

[sIGPIC]e[/sIGPIC]
Posted

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:

Never trouble another for what you can do for yourself.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...