O
oskilian ~at~ rapapaing #dot# com
I'm developing a small image editor as a component in my app in C#. I have the following Image
Image srcImage
Which is currently loaded with the image in the file, and I'm painting it into the Graphics of a PictureBox basically doing the following
private void pictureBox_Paint(object sender, PaintEventArgs e
Graphics dest = e.Graphics
dest.DrawImage(srcImage, destRect, srcRect, GraphicsUnit.Pixel)
And it works well. Now I need to pass through an intermediate Graphics, so I can do several changes to it before passing it on to the final destination. Since the only Blitting method I found for two memory GDI+ objects is Graphics.DrawImage(), I've only found a way to go from Bitmap to Graphics, but not the other way around, and there are no Graphics-Graphics Blitting methods, I chose to use the GDI. My new code goes like this
private void pictureBox_Paint(object sender, PaintEventArgs e
IntPtr hdcSrc
IntPtr hdcDest
Graphics src = Graphics.FromImage(srcImage)
Graphics dest = e.Graphics
hdcDest = dest.GetHdc()
hdcSrc = src.GetHdc();
// More GDI code will go here once I get this to work..
GDI.StretchBlt(hdcDest, destRect.X, destRect.Y, destRect.Width, destRect.Height
hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, RasterOperations.SRCCOPY)
src.ReleaseHdc()
src.Dispose()
dest.ReleaseHdc()
But the result is a black image. I have RasterOperations.SRCCOPY equal to 0x00CC0020. The interop invoke is properly defined, as using RasterOperations.WHITENESS=0x00FF0062 gives a white rectangle in the destination properly
My current guess is that Graphics.FromImage() is loading the image with some parameters incorrectly
I also tried this
private void pictureBox_Paint(object sender, PaintEventArgs e
IntPtr hdcSrc
IntPtr hdcDest
Graphics src = Graphics.FromImage(srcImage)
Graphics dest = e.Graphics
dest.DrawImageUnscaled(srcImage, 0, 0, srcImage.Width, srcImage.Height)
hdcDest = dest.GetHdc()
hdcSrc = src.GetHdc();
// More GDI code will go here once I get this to work..
GDI.StretchBlt(hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height
hdcDest, destRect.X, destRect.Y, destRect.Width, destRect.Height, RasterOperations.SRCCOPY)
GDI.StretchBlt(hdcDest, destRect.X, destRect.Y, destRect.Width, destRect.Height
hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, RasterOperations.SRCCOPY)
src.ReleaseHdc()
src.Dispose()
dest.ReleaseHdc()
And it works, probably because the first StretchBlt sets these missing parameters, but impressively, adding this
src.ReleaseHdc()
dest.ReleaseHdc()
hdcDest = dest.GetHdc()
hdcSrc = src.GetHdc()
between both calls to StretchBlt makes it fail again, probably because these parameters are lost when the HDC is released. The MSDN says that "Any state changes you make to the device context between GetHDC and ReleaseHDC will be ignored by GDI+ and will not be reflected in rendering done by GDI+." But it doesn't say what a "state" is
I would appreciate it if somebody told me how to either
* Perform managed StretchBlt operations between two Graphics objects
* Get the Bitmap out of a Graphics (to use Graphics.DrawImage()
* Get FromImage() to work properly when GDI calls are called upon the resulting Graphics.GetHdc(
o
* Know what do I have to change on a Graphics object after doing FromImage() so GDI calls on its hdc will work
Thank you very much, and please excuse my very long message, this is as short as I could make it
Oskilian
Image srcImage
Which is currently loaded with the image in the file, and I'm painting it into the Graphics of a PictureBox basically doing the following
private void pictureBox_Paint(object sender, PaintEventArgs e
Graphics dest = e.Graphics
dest.DrawImage(srcImage, destRect, srcRect, GraphicsUnit.Pixel)
And it works well. Now I need to pass through an intermediate Graphics, so I can do several changes to it before passing it on to the final destination. Since the only Blitting method I found for two memory GDI+ objects is Graphics.DrawImage(), I've only found a way to go from Bitmap to Graphics, but not the other way around, and there are no Graphics-Graphics Blitting methods, I chose to use the GDI. My new code goes like this
private void pictureBox_Paint(object sender, PaintEventArgs e
IntPtr hdcSrc
IntPtr hdcDest
Graphics src = Graphics.FromImage(srcImage)
Graphics dest = e.Graphics
hdcDest = dest.GetHdc()
hdcSrc = src.GetHdc();
// More GDI code will go here once I get this to work..
GDI.StretchBlt(hdcDest, destRect.X, destRect.Y, destRect.Width, destRect.Height
hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, RasterOperations.SRCCOPY)
src.ReleaseHdc()
src.Dispose()
dest.ReleaseHdc()
But the result is a black image. I have RasterOperations.SRCCOPY equal to 0x00CC0020. The interop invoke is properly defined, as using RasterOperations.WHITENESS=0x00FF0062 gives a white rectangle in the destination properly
My current guess is that Graphics.FromImage() is loading the image with some parameters incorrectly
I also tried this
private void pictureBox_Paint(object sender, PaintEventArgs e
IntPtr hdcSrc
IntPtr hdcDest
Graphics src = Graphics.FromImage(srcImage)
Graphics dest = e.Graphics
dest.DrawImageUnscaled(srcImage, 0, 0, srcImage.Width, srcImage.Height)
hdcDest = dest.GetHdc()
hdcSrc = src.GetHdc();
// More GDI code will go here once I get this to work..
GDI.StretchBlt(hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height
hdcDest, destRect.X, destRect.Y, destRect.Width, destRect.Height, RasterOperations.SRCCOPY)
GDI.StretchBlt(hdcDest, destRect.X, destRect.Y, destRect.Width, destRect.Height
hdcSrc, srcRect.X, srcRect.Y, srcRect.Width, srcRect.Height, RasterOperations.SRCCOPY)
src.ReleaseHdc()
src.Dispose()
dest.ReleaseHdc()
And it works, probably because the first StretchBlt sets these missing parameters, but impressively, adding this
src.ReleaseHdc()
dest.ReleaseHdc()
hdcDest = dest.GetHdc()
hdcSrc = src.GetHdc()
between both calls to StretchBlt makes it fail again, probably because these parameters are lost when the HDC is released. The MSDN says that "Any state changes you make to the device context between GetHDC and ReleaseHDC will be ignored by GDI+ and will not be reflected in rendering done by GDI+." But it doesn't say what a "state" is
I would appreciate it if somebody told me how to either
* Perform managed StretchBlt operations between two Graphics objects
* Get the Bitmap out of a Graphics (to use Graphics.DrawImage()
* Get FromImage() to work properly when GDI calls are called upon the resulting Graphics.GetHdc(
o
* Know what do I have to change on a Graphics object after doing FromImage() so GDI calls on its hdc will work
Thank you very much, and please excuse my very long message, this is as short as I could make it
Oskilian