Tôi cần hiển thị hình ảnh trực tiếp trên điều khiển WPF. Tôi đang tìm cách nhanh nhất để làm điều này bằng cách sử dụng WPF.Cách tạo BitmapImage từ mảng byte pixel (hiển thị video trực tiếp)
Tôi đang chụp ảnh từ máy ảnh bằng API dll (AVT).
Hình ảnh được ghi bởi dll và máy ảnh tăng một cuộc gọi lại với IntPtr đến cấu trúc Hình ảnh được gọi là tFrame (được mô tả bên dưới). Dữ liệu pixel được lưu trữ tại ImageBuffer propertie với một InPtr đến một mảng byte.
Tôi biết cách tạo Bitmap từ mảng byte pixel, nhưng không phải là BitmapImage. Vì vậy, nó có thể tạo ra một Bitmap và sau đó tạo ra một BitmapImagem từ nó. Here there is a way to create a BitmapImage from a Bitmap on the memory. Nhưng tôi muốn tạo trực tiếp BitmapImage từ nguồn dữ liệu (tFrame). Làm thế nào tôi có thể làm điều đó?
Tôi biết rằng BitmapImage có phương pháp CopyPixels, nhưng nó laks của một 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;
}
Đây là cách tôi tạo bitmap từ mảng byte pixel. Điều này đã được sử dụng ở phiên bản WinForm của phần mềm.
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:
Nhờ dr.mo, bây giờ tôi có thể hiển thị 60 FPS 1024x1024 hình ảnh với ~ 3% sử dụng CPU! Những gì tôi đang làm là:
//@ 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 – DarkSquirrel42
SEE này: http://stackoverflow.com/a/15290190/1507182 – Obama
@ DarkSquirrel42. Xin lỗi, liên kết bị hỏng. – Pedro77