项目名称:涂涂乐
项目简介:在多张背景图上选定一张,在这张背景图上实现绘图板功能,绘图界面大致如下:![CanvasPainter]
(https://img-blog.csdn.net/20160929155955015)
如图所示:左下的色板中可以选择画笔颜色,橡皮擦,三种笔和橡皮擦的宽度,右中部大部分是可作画区域
基本功能:三种宽度、二十种颜色的画笔和橡皮擦;图库canvas和画册canvas;截图功能;撤销功能(未完成)。
实现画笔的核心思路是对屏幕像素点的RGB值进行处理,获取鼠标按下并拖动最后到抬起的起始位置,根据宽度取坐标颜色并重置新的颜色;
橡皮擦与画笔相同,只是重置的颜色是透明的(在UI的最前端放置一张透明图,这样才不会抹去背景图的线条);
右下的绿色垃圾桶的作用是重置透明图,代码如下:
public void delete ()
{
int y=0 ;
int x=0 ;
Color color;
for (y = 0 ; y < baseTex.height; ++y)
{
for (x = 0 ; x < baseTex.width; ++x)
{
color =new Color(1.0f , 1.0f , 1.0f , 0.0f );
baseTex.SetPixel(x, y, color);
}
}
baseTex.Apply();
}
baseTex即是放置在背景图前的透明图,SetPixel对该坐标的一个像素点重置颜色color,前三个值为R、G、B,第四个值是透明度,
这里用两个for循环将baseTex上的所有像素点设为透明,以此来完成重置功能。
在UI中,新建的组件会出现在该目录的最下端,同时越下的UI物体层次越浅,也就出现在越前端。UI物体的RectTransform有两种,
简单理解为相对固定和填充,一般来说,为了不同的分辨率适配,我们需要一张填充类型的背景图,保证不管在多大分辨率的屏幕上都不会出现黑边。
***截图功能***:
IEnumerator UploadPNG()
{
yield return new WaitForEndOfFrame()
print("yuuuuu" )
int width = (int)(shibietu.transform .position .x - ul.transform .position .x ) * 2
int height = (int)(ul.transform .position .y - shibietu.transform .position .y ) * 2
int ulx = (int)(ul.transform .position .x )
int uly = Screen.height - (int)(ul.transform .position .y )
Debug.Log ("ulposition," + ulx + "," + uly)
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB 24, false)
//Texture2D tex = new Texture2D(width, height, TextureFormat.RGB 24, false)
tex.ReadPixels (new Rect(ulx, uly, width, height), 0 , 0 )
tex.Apply ()
byte[] bytes = tex.EncodeToPNG ()
Debug.Log ("bytes+" + bytes.Length )
string filename = System.DateTime .Now .Year .ToString ("0000" ) + System.DateTime .Now .Month .ToString ("00" ) +
System.DateTime .Now .Day .ToString ("00" ) + System.DateTime .Now .Hour .ToString ("00" ) +
System.DateTime .Now .Minute .ToString ("00" ) + System.DateTime .Now .Second .ToString ("00" ) +
Random.Range (0 , 9999 ).ToString ("0000" )
//filename = "hahah"
string oldFilePath = "G:/scan/scanimg/" + filename + ".png"
//string oldFilePath = Application.dataPath + filename + ".png"
Debug.Log (Application.dataPath )
//G:/ SVN画板 / UnityPaint / Assets
FileStream f = new FileStream(oldFilePath, FileMode.Create )
f.Write (bytes, 0 , bytes.Length )
//GetComponent<NetworkView>().RPC ("ReciveImage" , RPCMode.All , filename, bytes)
f.Flush ()
f.Close ()
System.GC .Collect ()
Resources.UnloadUnusedAssets ()
}
这里实现的是指定区域的截图并保存在指定文件夹内。值得一提的是我们首先要获得图片的左上和右下的坐标来确定截图区域,
而由于分辨率适配等原因我们需要进行一些傻傻的计算(我最早也是这么做的,各种计算),一个方便的解决办法是,
我们在UI里创建两个与背景图同目录下的空物体,分别将其拖到背景图上的左上顶点和右下顶点,无论分辨率和UI如何拉伸缩放,
这两个坐标总是在两个顶点位置。
![RawRexture](https://img-blog.csdn.net/20160929170858633)
三种canvas的切换:
最早的实现过程是创建了三个scene,除绘图板外还有图库场景和画册场景,经同事指点后采用了后来三个canvas的方法,具体操作没什么可说,
无非是各种启用和禁用(gameobject.SetActive(true/false))。
背景图的切换:
![这里写图片描述](https://img-blog.csdn.net/20160929171659930)
要实现UI上image的图片切换,要改变的是该物体的RawImage(Image)属性:
img.GetComponent<RawImage>().texture = allTex2d[GetButtonNum.ii + GetButtonNum.j];
这里我们需要TuKuCanvas下的脚本传值给PainterCanvas,因此需要个中间脚本来储存(当时是这么做的,应该有更好的方法),
需要定义的变量类型为:Public Static string/int/bool/enum。