我从相机中获取了镜头。像这样:
初始化:
uint pcount = (uint)(capGrabber.Width * capGrabber.Height * PixelFormats.Bgr32.BitsPerPixel / 8);
section = CreateFileMapping(new IntPtr(-1), IntPtr.Zero, 0x04, 0, pcount, null);
map = MapViewOfFile(section, 0xF001F, 0, 0, pcount);
BitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromMemorySection(section, capGrabber.Width, capGrabber.Height, PixelFormats.Bgr32, capGrabber.Width * PixelFormats.Bgr32.BitsPerPixel / 8, 0) as InteropBitmap;
capGrabber.Map = map;
,其中
IntPtr map;
IntPtr section;
InteropBitmap BitmapSource;
Graber(capGrabber):
public int BufferCB(double sampleTime, IntPtr pBuffer, int bufferLen)
{
if (Map != IntPtr.Zero)
{
CopyMemory(Map, pBuffer, bufferLen);
OnNewFrameArrived();
}
return 0;
}
我将图像颠倒(自上而下)。需要解决这个问题。我找到了一些东西(使用结构BITMAPINFO),但我没有工作。提出任何想法。
答案 0 :(得分:1)
问题似乎与Top-Down vs. Bottom-Up DIBs有关。
有些人添加WPF转换以将位图旋转180度,但我找到的最简单的解决方案是以相反的顺序复制位图,即替换
CopyMemory(Map, pBuffer, bufferLen);
通过
for(IntPtr pMap = Map, pBuf = pBuffer+bufferLen; pBuf.ToInt64() > pBuffer.ToInt64(); pMap += 4, pBuf -= 4)
CopyMemory(pMap, pBuf-4, 4);
注意数字4表示代表一个像素的字节数,即32位(RGB32)除以8。
答案 1 :(得分:1)
var target = m_Map;
var bytesPerRow = (m_Width * 4);
var source = aBuffer + aLength - bytesPerRow;
for (int i = m_Height - 1; i > 0; i--)
{
Interop.CopyMemory(target, source, bytesPerRow);
target += bytesPerRow;
source -= bytesPerRow;
}
性能更高。原始代码每次迭代需要224 467 428个刻度。每行复制仅需4 041 288个刻度
答案 2 :(得分:1)
Petr Gotthard考虑到了正确的问题,但代码并没有解决问题。
根据MSDN:
在自下而上的DIB中,图像缓冲区以底行像素开始,然后是下一行,依此类推。图像的顶行是缓冲区中的最后一行。因此,存储器中的第一个字节是图像的左下角像素。在GDI中,所有DIB都是自下而上的。下图显示了自底向上DIB的物理布局。
这意味着您的图像首先绘制底行,而不是顶行。这会产生垂直镜面效果。但是,它并没有反转左右。
考虑以下数组:
[ 0, 1, 2 ]
[ 3, 4, 5 ]
[ 6, 7, 8 ]
自上而下将按照说明读取和输出。但是自下而上会以这种方式解析它:
[ 6, 7, 8 ]
[ 3, 4, 5 ]
[ 0, 1, 2 ]
如果我们简单地撤销它,我们就会得到:
[ 2, 1, 0 ]
[ 5, 4, 3 ]
[ 8, 7, 6 ]
所以要把它放回去,我们需要步幅(宽度),然后我们逐行反转。
因此,考虑到Petr的答案并加大步伐,我们得到了这个:
int stride = Width * PixelFormats.Bgr32.BitsPerPixel / 8;
for (IntPtr pMap = Map, pBuf = buffer + bufferLen; pBuf.ToInt64() > buffer.ToInt64(); pMap += stride, pBuf -= stride)
CopyMemory(pMap, pBuf - stride, stride);