Comment créer un BitmapImage à partir d'un pixel tableau d'octets (en direct sur écran vidéo)

J'ai besoin d'afficher des images en direct sur un contrôle WPF. Je suis à la recherche de la façon la plus rapide pour ce faire, l'utilisation de WPF.

Je suis la capture d'images à partir d'un appareil photo à l'aide de son API dll (AVT).

L'image est rédigé par la dll et la caméra s'élève un rappel avec un IntPtr à une Image struct appelé tFrame (décrit ci-dessous). Les données de pixel est stocké à l'ImageBuffer biens est un InPtr à un tableau d'octets.

Je sais comment créer une image à partir du pixel tableau d'octets, mais pas un BitmapImage. Il est ainsi possible de créer une image Bitmap, puis de créer un BitmapImagem d'elle.
Ici, il ya une façon de créer un BitmapImage à partir d'une image sur la mémoire. Mais je veux créer la BitmapImage directement à partir de la source de données (tFrame). Comment puis-je le faire?

Je sais que BitmapImage ont un CopyPixels méthode, mais il laks d'un SetPixels.

public struct tFrame
{
    public IntPtr AncillaryBuffer;
    public uint AncillaryBufferSize;
    public uint AncillarySize;
    public tBayerPattern BayerPattern;
    public uint BitDepth;
    public tFrameCtx Context;
    public tImageFormat Format;
    public uint FrameCount;
    public uint Height;
    public IntPtr ImageBuffer;
    public uint ImageBufferSize;
    public uint ImageSize;
    public uint RegionX;
    public uint RegionY;
    public tErr Status;
    public uint TimestampHi;
    public uint TimestampLo;
    public uint Width;
}

Ici est de savoir comment je peux créer une image à partir d'un pixel du tableau d'octets. Il a été utilisé dans la WinForm version du logiciel.

private void CreateBitmap(tFrame frame)
{
    //This sample is for a 8bpp captured image
    PixelFormat pxFormat = PixelFormat.Format8bppIndexed;

    //STRIDE
    //[https://stackoverflow.com/questions/1983781/why-does-bitmapsource-create-throw-an-argumentexception/1983886#1983886][3]
    //float bitsPerPixel = System.Drawing.Image.GetPixelFormatSize(format);
    int bitsPerPixel = ((int)pxFormat >> 8) & 0xFF;
    //Number of bits used to store the image data per line (only the valid data)
    int validBitsPerLine = ((int)frame.Width) * bitsPerPixel;
    //4 bytes for every int32 (32 bits)
    int stride = ((validBitsPerLine + 31) / 32) * 4;

    Bitmap bmp = new Bitmap((int)frame.Width, (int)frame.Height, stride, pxFormat, frame.ImageBuffer);
}

EDIT 1:

Grâce à dr.mo, maintenant, je suis capable d'afficher 60 FPS 1024x1024 images avec ~3% d'utilisation du PROCESSEUR!
Ce que je fais est:

//@ UI Thread
public WriteableBitmap wbm = new WriteableBitmap(1024, 1024, (double)96, (double)96, System.Windows.Media.PixelFormats.Gray8, null);
this.wbBackBuffer = this.wbm.BackBuffer;

//This can be called by a timer in the UI thread or at the grab Thread for every image, the CPU usage is almost the same.
void UpdateDisplayImage()
{
wbm.Lock();
wbm.AddDirtyRect(new Int32Rect(0, 0, wbm.PixelWidth, wbm.PixelHeight));
wbm.Unlock();
}

//@ Grab Thread
//Update the backbuffer with new camera image data.
UpdateBackBuffer(...);

///<summary>
///[http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.aspx]
///</summary>
public void UpdateBackBuffer(IntPtr pData, int w, int h, int ch)
{
    //Can not acess wbm from outside UI thread
    //CopyMemory(wbm.BackBuffer, pData, (uint)(w * h * ch));
    //I dont know if it is safe to write to it buffer like this:
    CopyMemory(this.wbBackBuffer, pData, (uint)(w * h * ch));
}
  • msdn.microsoft.com/en-gb/library/system.windows.interop.imaging.createbitmapsourcefrommemorysection.aspx
  • VOIR ceci : stackoverflow.com/a/15290190/1507182
  • DarkSquirrel42. Désolé, le lien est rompu.
  • Merci, je vais tester cette solution.
InformationsquelleAutor Pedro77 | 2013-04-25