death_au's picture

Grabbing the rendered image as a Bitmap

Is there an easy way to grab something rendered in a glControl and store it in a Bitmap or Image object?
This is the code I'm using now:

Bitmap^ thumb = gcnew Bitmap(glControl->Width,glControl->Height);
Graphics^ gr = Graphics::FromImage(thumb);
gr->Clear(Color::White);
 
array<int>^ pixels = gcnew array<int>(3*thumb->Width*thumb->Height);
GL::ReadPixel(0, 0,
	glControl->Width,glControl->Height,
	PixelFormat::Rgb, PixelType::Int, pixels);
 
for(int y = 0; y < thumb->Height; y++)
	for(int x = 0; x < thumb->Width; x++)
		thumb->SetPixel(x,thumb->Height-y-1,Color::FromArgb(pixels[((thumb->Width*y )+ x)*3]));

I know the color interpretation is completely wrong, but before I fix that I'm wondering why I'm not getting the entire image. It grabs everything from the far left, to about 3/4 of the way to the right and cuts off there....

...This code is a mess because I've been trying different stuff all day, but it at least gives you an idea of where I'm at.


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
objarni's picture

It would be really nice to be able to write:

Bitmap bitmap = glControl.CreateBitmap(); // C#

:)

the Fiddler's picture

Just added this method to GLControl:

        #region public Bitmap GrabScreenshot()
 
        /// <summary>Grabs a screenshot of the frontbuffer contents.</summary>
        /// <returns>A System.Drawing.Bitmap, containing the contents of the frontbuffer.</returns>
        public Bitmap GrabScreenshot()
        {
            Bitmap bmp = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);
            System.Drawing.Imaging.BitmapData data = 
                bmp.LockBits(this.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly,
                             System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            GL.ReadPixels(0, 0, this.ClientSize.Width, this.ClientSize.Height, PixelFormat.Bgr, PixelType.UnsignedByte,
                          data.Scan0);
            bmp.UnlockBits(data);
            bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
            return bmp;
        }
 
        #endregion

Works perfectly here :)

Edit: Also fixed GL.ReadPixel, should have been GL.ReadPixels.

objarni's picture

Great, fast fix Fiddler! Does it work for both .NET and mono?

the Fiddler's picture

Couldn't test on Mono, because I've broken window creation in SVN. Seeing that this code works for Bitmap loading however, it will probably for saving too.

I'll test it as soon as I can get window creation to work.