Bitmap & Texture2D 互转方法搜集

Texture2D toBitmap 的方法

 

[csharp]  view plain  copy
  1. public static Bitmap FastTextureToBitmap(Texture2D texture)   
  2.         {   
  3.             // Setup pointer back to bitmap   
  4.             Bitmap newBitmap = new Bitmap(texture.Width, texture.Height);   
  5.             // Get color data from the texture   
  6.             Microsoft.Xna.Framework.Graphics.Color[ textureColors = GetColorDataFromTexture(texture);   
  7.             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);   
  8.             // Loop through pixels and set values   
  9.             unsafe   
  10.             {   
  11.                 byte* bmpPointer = (byte*)bmpData.Scan0;   
  12.                 for (int y = 0; y < texture.Height; y++)   
  13.                 {   
  14.                     for (int x = 0; x < texture.Width; x++)   
  15.                     {   
  16.                         bmpPointer[0] = textureColors[x + y * texture.Width].B;   
  17.                         bmpPointer[1] = textureColors[x + y * texture.Width].G;   
  18.                         bmpPointer[2] = textureColors[x + y * texture.Width].R;   
  19.                         bmpPointer[3] = textureColors[x + y * texture.Width].A;   
  20.                         bmpPointer += 4;   
  21.                     }   
  22.                     bmpPointer += bmpData.Stride - (bmpData.Width * 4);   
  23.                 }   
  24.             }   
  25.             textureColors = null;   
  26.             newBitmap.UnlockBits(bmpData);   
  27.             return newBitmap;   
  28.         }   

 

bitmap to texture2D 的方法:

[csharp]  view plain  copy
  1. private Texture2D GetTexture(GraphicsDevice dev, System.Drawing.Bitmap bmp)  
  2.       {  
  3.           int[] imgData = new int[bmp.Width * bmp.Height];  
  4.           Texture2D texture = new Texture2D(dev, bmp.Width, bmp.Height);  
  5.           unsafe  
  6.           {  
  7.               // lock bitmap  
  8.               System.Drawing.Imaging.BitmapData origdata =  
  9.                   bmp.LockBits(new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, bmp.PixelFormat);  
  10.               uint* byteData = (uint*)origdata.Scan0;  
  11.               // Switch bgra -> rgba  
  12.               for (int i = 0; i < imgData.Length; i++)  
  13.               {  
  14.                   byteData[i] = (byteData[i] & 0x000000ff) << 16 | (byteData[i] & 0x0000FF00) | (byteData[i] & 0x00FF0000) >> 16 | (byteData[i] & 0xFF000000);  
  15.               }  
  16.               // copy data  
  17.               System.Runtime.InteropServices.Marshal.Copy(origdata.Scan0, imgData, 0, bmp.Width * bmp.Height);  
  18.               byteData = null;  
  19.               // unlock bitmap  
  20.               bmp.UnlockBits(origdata);  
  21.           }  
  22.           texture.SetData(imgData);  
  23.           return texture;  
  24.       }  



貌似对于赋值这一步C#的效率好像不高,帧率一般都会降的很低。我还没有想到更好的办法,表示无奈中。。。 


实际上还有一个方法可以直接使用

BitmapSourceExtensions.CopyTo Method (BitmapSource, Texture2D)

此方法需要使用   System.Windows.Media.Imaging 我倒还没有尝试过。估计应该是挺好用的。
例子可以参见http://msdn.microsoft.com/en-us/library/gg712857(v=vs.96).aspx 
这种方法试过,但是不管用,自己也是新手,搞不定了。。。就扔了,有人搞懂的话,可以回个帖。~
值得一提的是对于BITMAP的格式,要值得仔细查看一下,不要直接套用上面的方法

这个是另外一种方法,试了一下貌似帧率有所提高,但依然还是不如窗体直接用的那种性能好。都准备放弃XNA了。。。
[csharp]  view plain  copy
  1.  1publicstatic Texture2D BitmapToTexture2D(   
  2. 2 GraphicsDevice GraphicsDevice,  
  3.  3 System.Drawing.Bitmap image)  
  4.  4{  
  5.  5 // Buffer size is size of color array multiplied by 4 because  
  6. 6// each pixel has four color bytes  
  7. 7int bufferSize = image.Height * image.Width * 4;   
  8. 8   
  9. // Create new memory stream and save image to stream so  
  10. 10// we don't have to save and read file   
  11. 11 System.IO.MemoryStream memoryStream =  
  12.  12 new System.IO.MemoryStream(bufferSize);  
  13. 13 image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Png);  
  14.  14 15 // Creates a texture from IO.Stream - our memory stream  
  15. 16 Texture2D texture = Texture2D.FromStream(  
  16.  17 GraphicsDevice, memoryStream);  
  17.  18 19return texture;  
  18. 20}   


我依然觉得这是个性能瓶颈。。。又搜到了国外某人发的一个类
[csharp]  view plain  copy
  1. using System;  
  2. using Microsoft.Xna.Framework;  
  3. using Microsoft.Xna.Framework.Graphics;  
  4. using System.Drawing;  
  5. using System.Drawing.Imaging;  
  6. using System.Runtime.InteropServices;  
  7.   
  8. namespace MrXNAHelper  
  9. {  
  10.     public class ImageToTexture  
  11.     {  
  12.         byte[] bmpBytes;  
  13.         Texture2D background;  
  14.   
  15.         int width, height;  
  16.         Game game;  
  17.         public ImageToTexture(Game game, int width, int height)  
  18.         {  
  19.             this.width = width;  
  20.             this.height = height;  
  21.             this.game = game;  
  22.   
  23.             GenerateBitmap(game, width, height);  
  24.         }  
  25.   
  26.         public ImageToTexture(Game game)  
  27.         {  
  28.             this.game = game;  
  29.         }  
  30.   
  31.         private void GenerateBitmap(Game game, int width, int height)  
  32.         {  
  33.             background = new Texture2D(game.GraphicsDevice, width, height);  
  34.         }  
  35.   
  36.         public Texture2D ConvertBitmapToTexture(Bitmap b)  
  37.         {  
  38.                 game.GraphicsDevice.Textures[0] = null;  
  39.                 if (background == null ||  
  40.                     b.Width != background.Width ||  
  41.                     b.Height != background.Height)  
  42.                 {  
  43.                     width = b.Width;  
  44.                     height = b.Height;  
  45.                     GenerateBitmap(game, width, height);  
  46.                 }  
  47.                   
  48.                 BitmapData bData = b.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(), b.Size),  
  49.                     ImageLockMode.ReadOnly,  
  50.                     PixelFormat.Format32bppRgb);  
  51.   
  52.                 // number of bytes in the bitmap  
  53.                 int byteCount = bData.Stride * b.Height;  
  54.                 if (bmpBytes == null ||  
  55.                     bmpBytes.Length != byteCount)  
  56.                     bmpBytes = new byte[byteCount];  
  57.   
  58.                 // Copy the locked bytes from memory  
  59.                 Marshal.Copy(bData.Scan0, bmpBytes, 0, byteCount);  
  60.   
  61.                 // don't forget to unlock the bitmap!!  
  62.                 b.UnlockBits(bData);  
  63.   
  64.                 background.SetData(bmpBytes);  
  65.   
  66.             return background;  
  67.         }  
  68.     }  
  69. }  
我终于会插代码了,,,,囧

现在知道降低XNA帧率或者自己写个定时器,总之不要使用60Hz的话,好像帧率也会有很大的提高。
[csharp]  view plain  copy
  1. byte[] bgrData = nextFrame.Bytes;  
  2.                     for (int i = 0; i < colorData.Length; i++)  
  3.                         colorData[i] = new Color(bgrData[3 * i + 2], bgrData[3 * i + 1], bgrData[3 * i]);  
惊人也没有用到什么内存指针之类的,但是就做到了。使用2张贴图交错的加载方法。膜拜老外啊。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值