当前位置: 首页 > news >正文

unity3D调用外接摄像头,保存图片、不使用截屏方式

首先感谢前辈使用截屏的方式调用外接摄像头并保存图片:http://blog.csdn.net/a112634313/article/details/8472786

Texture2D处理http://www.narkii.com/club/thread-291958-1.html

不多说,直接上我的代码

using UnityEngine;  
using System.Collections; 
using System.IO; 

public class CameraTest : MonoBehaviour  
{  
	public GameObject obj;
	WebCamTexture cameraTexture;  
	string cameraName="";  
	private bool isPlay = false;  
	// Use this for initialization  
	void Start()  
	{  
		StartCoroutine(Test());  
	}  
	
	// Update is called once per frame  
	void Update()  
	{  
		obj.renderer.material.mainTexture=cameraTexture;
	}  
	IEnumerator Test()  
	{  
		yield return Application.RequestUserAuthorization(UserAuthorization.WebCam);  
		if (Application.HasUserAuthorization(UserAuthorization.WebCam))  
		{  
			WebCamDevice[] devices = WebCamTexture.devices;  
			cameraName = devices[0].name;  
			cameraTexture = new WebCamTexture(cameraName, 400, 300, 15);  
			cameraTexture.Play();  
			isPlay = true;  
		}  
	}  
	void OnGUI()  
	{  
		if (isPlay)  
		{  
			GUI.DrawTexture(new Rect(0, 0, 400, 300), cameraTexture, ScaleMode.ScaleToFit);  
		}  
		if(GUI.Button(new Rect(400,0,450,50),"保存")){
			StartCoroutine(getTexture2d());

		}
		if(GUI.Button(new Rect(400,50,450,50),"AR")){
			Application.LoadLevel("HelloWorld");
			cameraTexture.Stop();
		}
	} 
	IEnumerator getTexture2d()
	{
		yield return new WaitForEndOfFrame();
		//Texture2D savedTexture ;//要保存图片的大小
		//截取的区域
		Texture2D savedTexture=obj.renderer.material.mainTexture as Texture2D;
		//截图方式
		/*
		  Texture2D t = new Texture2D(200, 200);//要保存图片的大小
//截取的区域
		t.ReadPixels(new Rect(0,cameraTexture.height, 400, 300), 0, 0, false);
t.Apply();
//把图片数据转换为byte数组
byte[] byt = t.EncodeToPNG();
//然后保存为图片
		File.WriteAllBytes(Application.dataPath + "/StreamingAssets/TutorialHelloWorld/"+"target1.png", byt);
}*/
		Texture2D texture = new Texture2D(cameraTexture.width, cameraTexture.height);
		int y = 0;    
		while (y < texture.height)  
		{          
			int x = 0;    
			while (x < texture.width)   
			{              
				Color color = cameraTexture.GetPixel(x, y);    
				texture.SetPixel(x, y, color);      
				++x;      
			}          
			++y;    
		}     
		texture.Apply();    
	byte[] pngData = texture.EncodeToPNG();	
		File.WriteAllBytes(Application.dataPath + "/StreamingAssets/TutorialHelloWorld/"+"target1.png", pngData);
	}
}  

说明一下,在场景中添加一个plane,我的目的就是将camera作为贴图放到panel上面来实时显示,因为我发现 WebCamTexture 不能直接作为Texture2D直接使用

之后点击保存按钮,将图片保存到指定路径:注意路径可以修改,不过没有的话它不会自己创建、会报错。看看结果



这样做和截屏相比有什么好处呢,我觉得:

1、截屏坐标需要你自己调节,unity3d默认坐标原点和截屏时候坐标原点是不一致的,一个在左上角一个在左下角,调节很麻烦

2、截屏方法一旦屏幕分辨率变化那么你的程序也要相应变化,不然会出问题

3、这种方式可以直接放到plane上或者任何Texture2D上,有很大的自由性,同时不需要担心图片是不是完整、有没有其他杂质什么的,摄像头获取的是什么,那么保存的图片就是什么。

最近又看到一种方法,就是截取相机的视野看到的内容,

Texture2D CaptureCamera(Camera camera, Rect rect)   
    {  
        // 创建一个RenderTexture对象  
        RenderTexture rt = new RenderTexture((int)rect.width, (int)rect.height, 0);  
        // 临时设置相关相机的targetTexture为rt, 并手动渲染相关相机  
        camera.targetTexture = rt;  
        camera.Render();  
        //ps: --- 如果这样加上第二个相机,可以实现只截图某几个指定的相机一起看到的图像。  
        //ps: camera2.targetTexture = rt;  
        //ps: camera2.Render();  
        //ps: -------------------------------------------------------------------  
        
        // 激活这个rt, 并从中中读取像素。  
        RenderTexture.active = rt;  
        Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24,false);  
        screenShot.ReadPixels(rect, 0, 0);// 注:这个时候,它是从RenderTexture.active中读取像素  
        screenShot.Apply();  
        
        // 重置相关参数,以使用camera继续在屏幕上显示  
        camera.targetTexture = null;  
        //ps: camera2.targetTexture = null;  
        RenderTexture.active = null; // JC: added to avoid errors  
        GameObject.Destroy(rt);  
        // 最后将这些纹理数据,成一个png图片文件  
        byte[] bytes = screenShot.EncodeToPNG();  
        string filename = Application.dataPath + "/Screenshot.png";  
        System.IO.File.WriteAllBytes(filename, bytes);  
        Debug.Log(string.Format("截屏了一张照片: {0}", filename));  
        
        return screenShot; 
}

注释很详细

相关文章:

  • Unity3D中Find的用法
  • Unity3D中世界坐标转换到NGUI坐标
  • Window8.1+VS2013+Python+cocos2d-x-3.2
  • Java环境配置好之后,cnd窗口Java可以执行,但是Javac不能执行
  • cocos2d-x import org.cocos2dx.lib cannot be resolved
  • C#字符串处理:裁剪,替换,移除
  • NGUI 创建自定义按钮并添加按钮响应
  • Metaio中关于镜像问题
  • Unity3D+Arduino控制LED灯泡
  • 【好程序员训练营】Java线程学习
  • 【好程序员特训营】Java的Io操作
  • 【好程序员特训营】Java异常处理
  • 【好程序员特训营】Java字符串截取分割
  • 【好程序员特训营】Java线程同步初探
  • 【好程序员特训营】Java中常用的排序方法
  • 《剑指offer》分解让复杂问题更简单
  • 3.7、@ResponseBody 和 @RestController
  • opencv python Meanshift 和 Camshift
  • orm2 中文文档 3.1 模型属性
  • Promise面试题2实现异步串行执行
  • ReactNativeweexDeviceOne对比
  • springboot_database项目介绍
  • 编写高质量JavaScript代码之并发
  • 不上全站https的网站你们就等着被恶心死吧
  • 成为一名优秀的Developer的书单
  • - 概述 - 《设计模式(极简c++版)》
  • 关于for循环的简单归纳
  • 利用阿里云 OSS 搭建私有 Docker 仓库
  • 普通函数和构造函数的区别
  • 找一份好的前端工作,起点很重要
  • k8s使用glusterfs实现动态持久化存储
  • shell使用lftp连接ftp和sftp,并可以指定私钥
  • 容器镜像
  • 我们雇佣了一只大猴子...
  • # 计算机视觉入门
  • #LLM入门|Prompt#1.8_聊天机器人_Chatbot
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (SpringBoot)第七章:SpringBoot日志文件
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (译)2019年前端性能优化清单 — 下篇
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .Net Core webapi RestFul 统一接口数据返回格式
  • .NET Core 成都线下面基会拉开序幕
  • .NET Standard、.NET Framework 、.NET Core三者的关系与区别?
  • .NET/C# 项目如何优雅地设置条件编译符号?
  • .net访问oracle数据库性能问题
  • @angular/cli项目构建--http(2)
  • @Autowired @Resource @Qualifier的区别
  • @Conditional注解详解
  • @Service注解让spring找到你的Service bean
  • []串口通信 零星笔记
  • []新浪博客如何插入代码(其他博客应该也可以)
  • [100天算法】-不同路径 III(day 73)
  • [2019.3.20]BZOJ4573 [Zjoi2016]大森林
  • [Android]Android P(9) WIFI学习笔记 - 扫描 (1)