本篇文章讲解Unity3d与Apache服务器交互时图片数据的传输,服务端语言使用php,关于apache和php的配置请参考Unity3D与Web服务器交互之Apache,PHP和Mysql配置,此处图片传输使用的是Post请求方式,关于post请求和get请求请参考:Unity3D与Web服务器交互之Get请求和Post请求示例,图片的传输需要把图片数据转换成byte[](字节数组)后进行传输,详情看代码。
进入正题,首先准备一张图片:
我们想实现以下效果:
当点击测试按钮时,将上面的那张图片上传到服务器同时再从服务器上面下载下来应用到下面的图片中,如下图:
实现步骤:
一、客户端工作:
新建一个工程,将熊猫图片导入到工程中,设置图片的属性:Texture Type选择Advanced,启用Read/Write Enable,如下图:
使用UGUI制作界面,一个按钮,两个Image,将熊猫图片赋予上面的Image,如下图:
创建一个空物体命名为TransmitPic,创建一个脚本TransmitPic,将该脚本挂到空物体上,脚本代码如下:
using UnityEngine; using System.Collections; using UnityEngine.UI; public class TransmitPic : MonoBehaviour { public Image upImage; public Image downImage; IEnumerator TransmitPicture() { byte[] bs = upImage.sprite.texture.EncodeToJPG(); //将该texture转成jpg格式图片,返回byte[]数据 WWWForm form = new WWWForm(); //WWWForm是一个辅助类,该类用于生成表单数据, //然后WWW类就可以将该表单数据post到web服务器上了 form.AddBinaryData("picture", bs, "filename", "image/jpg"); //添加二进制文件到表单,使用该函数可以上传文件或者图片到Web服务器 //第一个参数相当于一个"key",类似于html中表单的fieldname,服务器端根据这个"key"得到文件流 //所以在php文件中用_FILES["picture"]可以得到该文件 //上传的内容就是字节数组bs的内容 //第三个参数filename用于告诉服务器当保存上传文件时使用什么文件名 //最后一个参数是档案格式,此处我上传的是jpg格式,所以用image/jpg //如果bs使用的是png格式图片,就使用image/png WWW www = new WWW("http://127.0.0.1/unitypic.php", form); //该构造函数创建并发送一个post请求 //form包含着要被post到web服务器的表单数据(form data) //此时数据流也开始自动的下载web服务器的数据,可通过www访问下载到的数据 yield return www; //等待www完成,和下面代码功能相似 //while (!www.isDone) //{ // yield return null //} if (www.error != null) { Debug.Log(www.error); yield return null; } else { Texture2D tex = www.texture; //WWW.texture返回用下载下来的数据生成的texture2D Sprite spr = Sprite.Create(tex, upImage.sprite.rect, upImage.sprite.pivot, upImage.sprite.pixelsPerUnit); downImage.sprite = spr; yield return null; } } public void OnTestButton() { StartCoroutine(TransmitPicture()); } }
将场景中上下两个Image分别赋予public Image upImage和public Image downImage,将按钮点击响应函数设为public void OnTestButton()。
OK,客户端完成。
二、服务端工作:
打开apache和php配置一节中新建的www文件夹,创建一个新的php文件unitypic.php,代码如下:
<?php //isset()用于检测括号内的变量值是否设置了值, //如果变量存在且设置了非null值返回true,否则false //_FILES[]表示经由 HTTP POST 文件上传而提交至脚本的变量 //php中变量前面要加$ //echo表示输出 if(isset($_FILES["picture"])) //如果接收到了上传的数据 { echo file_get_contents($_FILES["picture"]["tmp_name"]); //file_get_contents() 函数把整个文件读入一个字符串中。 //tmp_name表示文件上传后 //在服务端存储的临时文件名 //一般是系统默认。可以在php.ini //的upload_tmp_dir 指定 } else { echo "error!"; }
OK,服务端工作完成。
三、测试:
打开Apache服务器(打开方式参看Apache配置一节),在Unity客户端测试,点击中间的测试按钮,出现如下图效果,则测试成功:
OK,测试成功!