I’m having a problem using StretchBlt to copy an image from a PictureBox to a Bitmap for use in creating an AVI file.
The AVI file is an unimportant aspect I believe - I can just display the Bitmap on another PictureBox and see the problem.
The problem is that occasionally (not often) a single image is flipped (mirrored across the X axis).
I’m not sure if this is a known problem with StretchBlt I haven’t yet found mention of or if I am doing something wrong.
It is NOT due to the intended functionality with StretchBlt of "If the signs of source and destination height or width are different then it creates a mirror image".
UPDATE: I changed things to force the source/destination to be the same size, and am using BitBlt with the same behavior.
I’ve included some code (c#), hopefully all of the important parts.
Stepping through the code I can see this happen for a single image that has exactly the same information being passed to StretchBlt (other than the hdc to copy to) as the previous image and the next image (and next, next) all of which are fine.
It doesn't happen often, and I dont see any reason when it does. Or a way to detect it happened (so I can flip it back).
I have a work around that doesn't use StretchBlt, but it is much slower and really degrades performance.
Another possibly useful bit: this flipped image is rare in normal usage (less than 1 in 100 frames). But when run in the IDE, stepping through image by image, it happens very regularly (maybe 1 in 10).
Any ideas what could be causing this or what I could be doing wrong? Or other FAST methods to copy the Bitmap including re-sizing.
NOTE: The bitmaps do vary in size (can't use BitBlt), but not by a lot.
Thank you!
Kate
[DllImport("GDI32.DLL", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
public static extern bool StretchBlt(
IntPtr hdcDest, int nXDest, int nYDest, int nDestWidth, int nDestHeight,
IntPtr hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, Int32 dwRop );
public class CAviImageInfo
{
private Bitmap mAviBitmap = null;
private Graphics mAviGraphics = null;
public CAviImageInfo(int width, int height )
{
mAviBitmap = new Bitmap(width, height);
mAviGraphics = Graphics.FromImage(mAviBitmap);
}
~CAviImageInfo()
{
mAviGraphics.Dispose();
mAviGraphics = null;
}
public Bitmap AviBitmap
{ get { return mAviBitmap; } }
public Graphics AviGraphics
{ get { return mAviGraphics; } }
}
PictureBox mMainPictureBox;
PictureBox DebugPictureBox;
Graphics mMainPictureBoxGraphics = mMainPictureBox.CreateGraphics();
IntPtr mMainPictureBoxHdc = mMainPictureBoxGraphics.GetHdc();
Public void UpdateAviRecording()
{
CAviImageInfo aviImageInfo = GetUnusedAviImageInfo();
IntPtr destinationHdc = aviImageInfo.AviGraphics.GetHdc();
StretchBlt(
destinationHdc,
0, 0, aviImageInfo.AviBitmap.Width, aviImageInfo.AviBitmap.Height,
mMainPictureBoxHdc,
0, 0, mMainPictureBox.Width, mMainPictureBox.Height, SRCCOPY);
DebugPictureBox.Image = aviImageInfo.AviBitmap;
DebugPictureBox.Refresh();
aviImageInfo.AviGraphics.ReleaseHdc(destinationHdc);
}