赞
踩
最近学习emgucv,我在写读摄像头的程序然后需要bitmap 转texture2D 其实可以直接使用setdata<bytes>的方法赋值,感觉帧率不是一般的低,是无法忍受的。
也试了多种方法,基本上都是无法忍受的。可能有人会用得到,将搜集的列下来。
这是一些方法的搜集。
Texture2D toBitmap 的方法
- public static Bitmap FastTextureToBitmap(Texture2D texture)
- {
- // Setup pointer back to bitmap
- Bitmap newBitmap = new Bitmap(texture.Width, texture.Height);
- // Get color data from the texture
- Microsoft.Xna.Framework.Graphics.Color[ textureColors = GetColorDataFromTexture(texture);
- System.Drawing.Imaging.BitmapData bmpData = newBitmap.LockBits(new System.Drawing.Rectangle(0, 0, newBitmap.Width, newBitmap.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
- // Loop through pixels and set values
- unsafe
- {
- byte* bmpPointer = (byte*)bmpData.Scan0;
- for (int y = 0; y < texture.Height; y++)
- {
- for (int x = 0; x < texture.Width; x++)
- {
- bmpPointer[0] = textureColors[x + y * texture.Width].B;
- bmpPointer[1] = textureColors[x + y * texture.Width].G;
- bmpPointer[2] = textureColors[x + y * texture.Width].R;
- bmpPointer[3] = textureColors[x + y * texture.Width].A;
- bmpPointer += 4;
- }
- bmpPointer += bmpData.Stride - (bmpData.Width * 4);
- }
- }
- textureColors = null;
- newBitmap.UnlockBits(bmpData);
- return newBitmap;
- }
bitmap to texture2D 的方法:
- private Texture2D GetTexture(GraphicsDevice dev, System.Drawing.Bitmap bmp)
- {
- int[] imgData = new int[bmp.Width * bmp.Height];
- Texture2D texture = new Texture2D(dev, bmp.Width, bmp.Height);
- unsafe
- {
- // lock bitmap
- System.Drawing.Imaging.BitmapData origdata =
- bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);
- uint* byteData = (uint*)origdata.Scan0;
- // Switch bgra -> rgba
- for (int i = 0; i < imgData.Length; i++)
- {
- byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);
- }
- // copy data
- System.Runtime.InteropServices.Marshal.Copy(origdata.Scan0, imgData, 0, bmp.Width * bmp.Height);
- byteData = null;
- // unlock bitmap
- bmp.UnlockBits(origdata);
- }
- texture.SetData(imgData);
- return texture;
- }
貌似对于赋值这一步C#的效率好像不高,帧率一般都会降的很低。我还没有想到更好的办法,表示无奈中。。。
实际上还有一个方法可以直接使用
- 1publicstatic Texture2D BitmapToTexture2D(
- 2 GraphicsDevice GraphicsDevice,
- 3 System.Drawing.Bitmap image)
- 4{
- 5 // Buffer size is size of color array multiplied by 4 because
- 6// each pixel has four color bytes
- 7int bufferSize = image.Height * image.Width * 4;
- 8
- 9 // Create new memory stream and save image to stream so
- 10// we don't have to save and read file
- 11 System.IO.MemoryStream memoryStream =
- 12 new System.IO.MemoryStream(bufferSize);
- 13 image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);
- 14 15 // Creates a texture from IO.Stream - our memory stream
- 16 Texture2D texture = Texture2D.FromStream(
- 17 GraphicsDevice, memoryStream);
- 18 19return texture;
- 20}
- using System;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Runtime.InteropServices;
-
- namespace MrXNAHelper
- {
- public class ImageToTexture
- {
- byte[] bmpBytes;
- Texture2D background;
-
- int width, height;
- Game game;
- public ImageToTexture(Game game, int width, int height)
- {
- this.width = width;
- this.height = height;
- this.game = game;
-
- GenerateBitmap(game, width, height);
- }
-
- public ImageToTexture(Game game)
- {
- this.game = game;
- }
-
- private void GenerateBitmap(Game game, int width, int height)
- {
- background = new Texture2D(game.GraphicsDevice, width, height);
- }
-
- public Texture2D ConvertBitmapToTexture(Bitmap b)
- {
- game.GraphicsDevice.Textures[0] = null;
- if (background == null ||
- b.Width != background.Width ||
- b.Height != background.Height)
- {
- width = b.Width;
- height = b.Height;
- GenerateBitmap(game, width, height);
- }
-
- BitmapData bData = b.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(), b.Size),
- ImageLockMode.ReadOnly,
- PixelFormat.Format32bppRgb);
-
- // number of bytes in the bitmap
- int byteCount = bData.Stride * b.Height;
- if (bmpBytes == null ||
- bmpBytes.Length != byteCount)
- bmpBytes = new byte[byteCount];
-
- // Copy the locked bytes from memory
- Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);
-
- // don't forget to unlock the bitmap!!
- b.UnlockBits(bData);
-
- background.SetData(bmpBytes);
-
- return background;
- }
- }
- }
我终于会插代码了,,,,囧
- byte[] bgrData = nextFrame.Bytes;
- for (int i = 0; i < colorData.Length; i++)
- colorData[i] = new Color(bgrData[3 * i + 2], bgrData[3 * i + 1], bgrData[3 * i]);
惊人也没有用到什么内存指针之类的,但是就做到了。使用2张贴图交错的加载方法。膜拜老外啊。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。