处理2D图像和纹理——创建一张纹理,定义每个像素的颜色,将纹理保存到一个文件
2010-11-26 10:53
375 查看
问题
你想创建一张新纹理并手动定义每个像素的颜色。当你想让用户创建一个新图像或生成诸如深度贴图之类的人工图像时是很有用的。
你想将这张纹理存储到文件中,例如,生成游戏截图或为了调试的目的。
解决方案
设置一张图像的颜色和将纹理用你选择的格式保存到一个文件中被XNA Framework直接支持。
你可以通过调用纹理的SetData方法改变它的内容,这个方法以一个包含每个像素颜色值的数组为参数。
你可以使用纹理的Save方法将它保存到一个文件中。
工作原理
首先创建一个数组,保存图像中每个像素的颜色:
上述代码首先创建一个可以为一个分辨率为512×512的纹理存储颜色的数组。然后使用两个for循环分别填充每个像素。使用这个填充顺序,你首先从左上角开始,沿着从左向右,从上到下的顺序遍历像素。
最后,你需要实际创建纹理并将数组中的内容加载到纹理内存中:
然后,在device和图像分辨率之后,你需要指定mipmap的数量(见后面的注意事项)。下一个参数让你可以设置TextureUsage。通过选择TextureUsage.AutoGenerateMipMap,XNA会自动生成你指定的mipmaps的数量。记住,如果你想使用mipmap,图像的宽和高必须是2的整数幂。
注意:一个mipmapped图像包含图像的多个分辨率,这在很多情况下是很有用得。当绘制一个3D场景时,如果一个带纹理的盒子距相机如此之远以至于在窗口中只有一个像素的大小。要确定盒子的颜色,显卡仍需要计算从哪个纹理坐标采样纹理。当稍微移动一下相机,纹理坐标可能会有少许不同,但可能对应纹理中一个截然不同的颜色。结果是,稍微一动一个相机也会导致盒子的颜色发生变化,导致屏幕上像素的闪烁。一个解决方法是在图像中存储不同分辨率的多个版本。对一个64 × 64像素的图像,如果你开启mipmapping,XNA还会在图像中创建32 × 32,16 × 16,8 × 8,4 × 4,2 × 2直到1 × 1的版本, 1 × 1图像的单个像素就是整个纹理的颜色。现在,在刚才很远的盒子的情况中,XNA会使用图像的1 × 1。这样,纹理坐标的变化不会导致颜色的变化,闪烁的像素会保持一个不变的颜色!
最后一个参数指定了纹理中像素的格式,这对XNA分配足够的内存存储纹理是必须的。 而且,当获取纹理中的值时,这也是你预期的格式,当你将数据写入到纹理时,必须提供这个格式的数据。
最后,只需简单地将Color数组存储在纹理中:
将纹理保存到文件还要简单:
最后一个参数指定文件的压缩格式,确保文件扩展名对应这个格式,否则试图从一个外部图像浏览器打开这个文件会遇到麻烦。
当运行这个代码时,文件会创建到与可执行文件相同的位置中。默认是在\bin\x86\Debug文件夹中。
代码
下面的代码创建一个纹理,使用颜色数据进行填充并返回这个纹理:
这个方法需要从LoadContent方法中调用,因为它需要设备实例化:
你想创建一张新纹理并手动定义每个像素的颜色。当你想让用户创建一个新图像或生成诸如深度贴图之类的人工图像时是很有用的。
你想将这张纹理存储到文件中,例如,生成游戏截图或为了调试的目的。
解决方案
设置一张图像的颜色和将纹理用你选择的格式保存到一个文件中被XNA Framework直接支持。
你可以通过调用纹理的SetData方法改变它的内容,这个方法以一个包含每个像素颜色值的数组为参数。
你可以使用纹理的Save方法将它保存到一个文件中。
工作原理
首先创建一个数组,保存图像中每个像素的颜色:
int textureWidth = 512; int textureHeight = 512; Color[] textureColors = new Color[textureWidth* textureHeight]; int i = 0; for (int ver = 0; ver < textureHeight; ver++) for (int hor=0; hor<textureWidth; hor++) { float red = (float)hor / (float)textureWidth; float green = 0; float blue = (float)ver / (float)textureHeight; float alpha = 1; textureColors[i++] = new Color(new Vector4(red, green, blue, alpha)); }
上述代码首先创建一个可以为一个分辨率为512×512的纹理存储颜色的数组。然后使用两个for循环分别填充每个像素。使用这个填充顺序,你首先从左上角开始,沿着从左向右,从上到下的顺序遍历像素。
最后,你需要实际创建纹理并将数组中的内容加载到纹理内存中:
Texture2D newTexture = new Texture2D(device, textureWidth, textureHeight, 1, TextureUsage.None, SurfaceFormat.Color);
然后,在device和图像分辨率之后,你需要指定mipmap的数量(见后面的注意事项)。下一个参数让你可以设置TextureUsage。通过选择TextureUsage.AutoGenerateMipMap,XNA会自动生成你指定的mipmaps的数量。记住,如果你想使用mipmap,图像的宽和高必须是2的整数幂。
注意:一个mipmapped图像包含图像的多个分辨率,这在很多情况下是很有用得。当绘制一个3D场景时,如果一个带纹理的盒子距相机如此之远以至于在窗口中只有一个像素的大小。要确定盒子的颜色,显卡仍需要计算从哪个纹理坐标采样纹理。当稍微移动一下相机,纹理坐标可能会有少许不同,但可能对应纹理中一个截然不同的颜色。结果是,稍微一动一个相机也会导致盒子的颜色发生变化,导致屏幕上像素的闪烁。一个解决方法是在图像中存储不同分辨率的多个版本。对一个64 × 64像素的图像,如果你开启mipmapping,XNA还会在图像中创建32 × 32,16 × 16,8 × 8,4 × 4,2 × 2直到1 × 1的版本, 1 × 1图像的单个像素就是整个纹理的颜色。现在,在刚才很远的盒子的情况中,XNA会使用图像的1 × 1。这样,纹理坐标的变化不会导致颜色的变化,闪烁的像素会保持一个不变的颜色!
最后一个参数指定了纹理中像素的格式,这对XNA分配足够的内存存储纹理是必须的。 而且,当获取纹理中的值时,这也是你预期的格式,当你将数据写入到纹理时,必须提供这个格式的数据。
最后,只需简单地将Color数组存储在纹理中:
newTexture.SetData<Color>(textureColors);
将纹理保存到文件还要简单:
myTexture.Save("savedtexture.jpg", ImageFileFormat.Jpg);
最后一个参数指定文件的压缩格式,确保文件扩展名对应这个格式,否则试图从一个外部图像浏览器打开这个文件会遇到麻烦。
当运行这个代码时,文件会创建到与可执行文件相同的位置中。默认是在\bin\x86\Debug文件夹中。
代码
下面的代码创建一个纹理,使用颜色数据进行填充并返回这个纹理:
private Texture2D DefineTextureColors() { int textureWidth = 512; int textureHeight = 512; Color[] textureColors = new Color[textureWidth* textureHeight]; int i = 0; for (int ver = 0; ver < textureHeight; ver++) for(int hor=0; hor<textureWidth; hor++) { textureColors[i++] = new Color(new Vector4((float)hor / (float)textureWidth, 0, (float)ver / (float)textureHeight, 1)); } Texture2D newTexture = new Texture2D(device, textureWidth, textureHeight, 1, ResourceUsage.None, SurfaceFormat.Color); newTexture.SetData<Color>(textureColors); return newTexture; }
这个方法需要从LoadContent方法中调用,因为它需要设备实例化:
protected override void LoadContent()
{
device = graphics.GraphicsDevice;
spriteBatch = new SpriteBatch(GraphicsDevice);
myTexture = DefineTextureColors();myTexture.Save("savedtexture.jpg", ImageFileFormat.Jpg);
}
相关文章推荐
- 处理2D图像和纹理——创建一个3D爆炸效果,简单的粒子系统
- 处理2D图像和纹理——旋转,缩放和镜像一张图像
- 处理2D图像和纹理——创建2D菜单界面
- 一张图像表示成NxN的矩阵,图像中每个像素是4个字节,写一个函数把图像旋转90度。 你能原地进行操作吗?(即不开辟额外的存储空间)
- 灰度图像像素颜色亮度处理
- 使用 Java 进行图像处理 - 取得图像上指定位置像素的 rgb 颜色分量
- 让我蛋疼了好久的2D游戏图像颜色处理
- Hibernate映射类继承之每个带有联合的具体类一张表(每个子类各一张表,共用一个父类映射文件)
- 【数字图像处理】C++读取、旋转和保存bmp图像文件编程实现
- CxImage与OpenGL结合,用于读入多种格式的纹理以及用来把屏幕保存为各种格式的图像文件。 关于CxImage的文章,网上有许多,这里只介绍如何把CxImage与OpenGL结合起来,用于读
- MATLAB图像处理基础知识3 稀疏矩阵变全矩阵full 保存矩阵到txt文件save
- SilverLight学习笔记--如何在xaml文件中操作用户在后台代码定义的类(2)--示例篇:创建一个登录控件(原创)(转载本文请注明出处)
- 有一个一维整型数组int[]data保存的是一张宽为width,高为height的图片像素值信息。请写一个算法,将该图片所有的白色不透明(0xffffffff)像素点的透明度调整为50%。
- android中Bitmap图像处理 修改图片大小以及保存时的文件大小
- 创建一个xml文件(c:/test.html),为该文件增加三个节点,,,将b的attribute改为4并保存
- hdu6035 Colorful Tree 树形dp 给定一棵树,每个节点有一个颜色值。定义每条路径的值为经过的节点的不同颜色数。求所有路径的值和。
- 窗口作业1 作业: 1.创建一个窗口程序(JFrame),标题栏起名为“浏览器”,有一个菜单条,有“文件”、“编辑”、“查看”3个菜单。“文件”菜单有两个菜单项,一项是“打开”,一项是“保存
- 【OpenCV应用笔记】(彩色/灰度)图像像素值读取并保存到txt文件
- Java定义一个用来保存全局字符串的properties文件并用ResourceBundle读取它
- MATLAB读取图像的每一帧处理之后保存成视频文件