unity图像处理
图像处理主要有这些类
-
Graphics
- Blit 纹理通过材质渲染到目标,纹理设为材质的 _MainTex 属性
将 dest 设置为渲染目标,为null时直接渲染到屏幕,使用后RenderTexture.active变成dest
该操作在GPU上复制纹理,速度很快
在 android 上如果不生效,尝试创建 RenderTexture 时深度值设为0
scale 和 offset 不使用材质时才有,用来设置uv偏移和缩放 - ConvertTexture 在不同格式和尺寸的纹理之间进行转换的有效方式
注意 Blit 目标是 RenderTexture ,ConvertTexture 目标是 Texture2D
ConvertTexture 对目标格式也有要求,必须是 RenderTarget 支持的格式,目前只测出支持 ARBG32 - CopyTexture 高效复制,大小必须相同,格式必须一致
- DrawMesh 绘制网格,只是提交到渲染队列
- DrawTexture 在屏幕坐标系中绘制纹理,只能在OnGUI以及之后的生命周期方法中调用,否则无法显示。
- SetRenderTarget 设置当前渲染目标
- Blit 纹理通过材质渲染到目标,纹理设为材质的 _MainTex 属性
-
Texture2D
- ReadPixels 读取屏幕缓存到Texture2D,先通过 RenderTexture.active=XXX; 关联,就可以读取XXX
该函数从GPU上读取像素到CPU
如果只是用来获取像素数据,不需要渲染,则不要调用 Texture2D.Apply ,因为很耗时
如果要用来渲染,则要调用 Texture2D.Apply - EncodeToPNG 编码成图像文件格式
- EncodeToJPG
- ReadPixels 读取屏幕缓存到Texture2D,先通过 RenderTexture.active=XXX; 关联,就可以读取XXX
-
ImageConversion 图像编解码
- EncodeToPNG
- EncodeToJPG
- UnsafeEncodeNativeArrayToPNG
- UnsafeEncodeNativeArrayToJPG
-
RenderTexture 只包含GPU上的数据,要获取cpu上的数据(比如像素字节数组),需要使用 Texture2D.ReadPixels 从 GPU 传到 CPU
-
ScreenCapture 截屏
- CaptureScreenshot 截屏保存成png
- CaptureScreenshotAsTexture 截屏保存成 Texture2D
- CaptureScreenshotIntoRenderTexture 截屏保存成 RenderTexture
-
WebCamTexture 捕获手机相机画面,可以参考 OpenCVForUnity\org\opencv\unity\helper\WebCamTextureToMatHelper.cs
图像处理的一般流程
- 渲染到 RenderTexture
使用 Graphics.Blit
或者 设置 Camera.targetTexture 然后调用 Camera.Render() - 用 RenderTexture 生成 Texture2D
使用 Texture2D.ReadPixels - 将 Texture2D 保存成文件或设置给 RawImage 进行显示
使用 Texture2D.EncodeToPNG
动态创建材质
// shaderName 是可以在任何材质的着色器弹出窗口中看到的名称,例如“Standard”、“Unlit/Texture”、“Legacy Shaders/Diffuse”等
// 场景中必须有对象引用了着色器,否则着色器有可能缺失
// 可以直接把着色器添加到 ProjectSettings->Graphics->Built-in Shader Settings->Always included shaders
// 如果只是某个平台用,可以加到 ProjectSettings->Player->Android->Other Settings->PreloadAssets
Shader shader = Shader.Find(shaderName);
Material material = new Material(shader);
创建RenderTexture
public static RenderTexture CreateRenderTexture(int width, int height, int depth = 24,
RenderTextureFormat format = RenderTextureFormat.ARGB32, bool usequaAnti = true)
{
var rt = new RenderTexture(width, height, depth, format);
rt.wrapMode = TextureWrapMode.Clamp;
if (QualitySettings.antiAliasing > 0 && usequaAnti)
{
rt.antiAliasing = QualitySettings.antiAliasing;
}
rt.Create();
return rt;
}
RenderTexture rt = CreateRenderTexture(1024,720,24,RenderTextureFormat.ARGB32);
// 如果是临时使用,经常使用
RenderTexture renderTexture = RenderTexture.GetTemporary(texture2D.width, texture2D.height);
// 使用 renderTexture 后释放
RenderTexture.ReleaseTemporary(renderTexture);
RenderTexture 和 Texture2D 互转
RenderTexture 代表GPU纹理,Texture2D 代表CPU纹理,当要操作纹理时使用 RenderTexture 更快,当要操作数据时使用 Texture2D
-
RenderTexture 转 Texture2D
-
方法一:
Texture2D tex = new Texture2D(renderTexture.width, renderTexture.height, TextureFormat.RGB24, false); var prevActive = RenderTexture.active; RenderTexture.active = renderTexture; // ReadPixels 读取当前渲染目标某个区域的像素并写入 tex 中,[0,0] 表示左下 tex.ReadPixels(new Rect(0, 0, renderTexture.width, renderTexture.height), 0, 0); // Apply 把纹理数据上传给GPU,如果这个纹理只是用来获取像素数据,不需要渲染,则不要调用该函数,因为很耗时 tex.Apply(); RenderTexture.active = prevActive;
-
方法二:
renderTexture.enableRandomWrite = true; Texture2D tex = new Texture2D</
-