我在使用 StretchBlt(或 BitBlt)将图像从 PictureBox 复制到位图以用于创建 AVI 文件时遇到问题。我相信 AVI 文件是一个不重要的方面——我可以在另一个 PictureBox 上显示位图并查看问题。
问题是偶尔(不经常)单个图像被翻转(镜像跨 X 轴,而不是 Y 轴)。我不确定这是否是我尚未发现提及的 StretchBlt 的已知问题,或者我做错了什么。
请注意,这不是由于 StretchBlt 的预期功能“如果源和目标高度或宽度的符号不同,则它会创建镜像”。
更新:我更改了一些东西以强制源/目标大小相同,并且使用具有相同行为的 BitBlt。
我已经包含了一些代码(c#),希望是所有重要的部分。
单步执行代码,我可以看到单个图像发生这种情况,该图像具有与前一个图像和下一个图像(以及下一个,下一个)完全相同的信息传递给 StretchBlt(除了要复制到的 hdc),所有这些都是美好的。它不经常发生,我看不出有什么原因。或者一种检测它发生的方法(所以我可以把它翻转回来)。我有一个不使用 StretchBlt 的解决方法,但它的速度要慢得多,并且确实会降低性能。
另一个可能有用的位:这个翻转的图像在正常使用中很少见(100 帧中少于 1 个)。但是当在 IDE 中运行时,逐个图像地逐个执行,它会非常频繁地发生(可能是十分之一)。
任何想法可能导致这种情况或我可能做错了什么?或其他快速复制位图的方法,包括调整大小。注意:位图的大小确实不同(不能使用 BitBlt),但差别不大。
谢谢!
凯特
// --- Import statement
[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 );
// --- A small class for creating/storing Bitmap and Graphics objects, which get reused
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; } }
}
// --- Two PictureBoxs placed on form at design time (one is just to watch for these mirrored images):
PictureBox mMainPictureBox; // --- Displays the images to be copied
PictureBox DebugPictureBox;
// --- The following done one time:
Graphics mMainPictureBoxGraphics = mMainPictureBox.CreateGraphics();
IntPtr mMainPictureBoxHdc = mMainPictureBoxGraphics.GetHdc();
// --- Method that does the copying. Called each time image on panel is updated.
Public void UpdateAviRecording()
{
// --- Gets unused Bitmap and Graphics objects (these are reused)
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);
// --- Show the copied Bitmap on the debug PictureBox
// --- (normally would pass it to be written to avi file)
DebugPictureBox.Image = aviImageInfo.AviBitmap;
DebugPictureBox.Refresh();
aviImageInfo.AviGraphics.ReleaseHdc(destinationHdc);
}