这篇内容旨在详细介绍我在完成涂涂乐这个项目中用到的关于文件存储命名等的思路和操作。
(一)截图操作
截图的基本思路:在绘图区域确定一个矩形,创建一个Texture2D获取这部分像素并生成图片存储在文件夹中。
IEnumerator ScreenSHOT()
{
yield return new WaitForEndOfFrame();
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);
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(ulx, (int)ru.transform.position.y, width, height), 0, 0);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
string filenameTimeNum = "";
if (ButtonControl.FromHuaCeLoad == false)
{
//Debug.Log("bieaaaa");
string filename = AnimalsName[GetButtonNum.i + GetButtonNum.j];
filenameTimeNum = 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") + AnimalsName[GetButtonNum.i + GetButtonNum.j] + ".png";
}
//如果加载按钮触发,即加载的图片来自相册,执行对图片名称的操作
if (ButtonControl.FromHuaCeLoad == true)
{
//Debug.Log("ScreenShotBefore");
load();
DirectoryInfo theFloder = new DirectoryInfo(scanpathh);
FileInfo NameInfo = theFloder.GetFiles()[GetButtonNum.ii + GetButtonNum.jj];
//Debug.Log("LoadTheimg:" + (GetButtonNum.ii + GetButtonNum.jj));
//Debug.Log("quanming" + NameInfo.Name);
string fileTimeNum = "";
string fileNameInfo = "";
for (int i = 0; i < 18; i++)
{
if ((NameInfo.Name[i] >= 48 || NameInfo.Name[i] <= 57))
{
fileTimeNum += NameInfo.Name[i].ToString();
//fileNameInfo += NameInfo.Name[i].ToString();
//Debug.Log("fileNameInfo:" + fileNameInfo);
}
}
fileNameInfo = NameInfo.Name.Remove(0, 18);
//Debug.Log("filenameinfo:" + fileNameInfo);
filenameTimeNum = 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") + fileNameInfo;
ButtonControl.FromHuaCeLoad = false;
}
//Debug.Log("filename"+filename);
string filenamedd = "hahah";
//string oldFilePathh = "G:/scan/scanimgg/" + filename + ".png";
//string oldFilePath = "G:/scan/scanimg/" + filename + ".png";
string oldFilePathh = scanpathh + "/" + filenameTimeNum;
string oldFilePath = scanpath + "/" + filenameTimeNum;
//string oldFilePath = Application.dataPath + filename + ".png";
//Debug.Log(Application.dataPath);
//G:/ SVN画板 / UnityPaint / Assets
FileStream f = new FileStream(oldFilePath, FileMode.Create);
FileStream ff = new FileStream(oldFilePathh, FileMode.Create);
f.Write(bytes, 0, bytes.Length);
ff.Write(bytes, 0, bytes.Length);
GetComponent<NetworkView>().RPC("ReciveImage", RPCMode.All, filenamedd, filenameTimeNum, bytes);
f.Flush();
f.Close();
ff.Flush();
ff.Close();
System.GC.Collect();
Resources.UnloadUnusedAssets();//卸载未使用的资源
if (ButtonControl.isTuKu2&&!justSave)
{
justPainter.SetActive(false);
TuCeng.SetActive(true);
canvasTuKu.SetActive(true);
ButtonControl.isTuKu2 = false;
}
if(ButtonControl.isAlbum2&&!justSave)
{
justPainter.SetActive(false);
TuCeng.SetActive(true);
canvasHuaLang.SetActive(true);
ButtonControl.isAlbum2 = false;
}
justSave = false;
}
ulx,uly确定截图矩形区域的左上顶点坐标,width和height确定矩形宽高
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(ulx, (int)ru.transform.position.y, width, height), 0, 0);
tex.Apply();
在每次结束了像素操作(Get、Set、Read)后都必须Texture.Apply()。
这样我们就得到了一个截图Texture,接下来把它变成一张图片。
scanpath = Directory.GetParent(Application.dataPath).ToString() + "/scan/scanimg";
用该操作获得Data根目录下的相对路径。
filenameTimeNum = 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") + AnimalsName[GetButtonNum.i + GetButtonNum.j] + ".png";
根据执行该条语句时的时间来为文件命名。
byte[] bytes = tex.EncodeToPNG();
该函数仅工作于ARGB32和RGB24格式。该纹理在纹理导入设置必须具有可读写标识。我们用这个函数来获得Texture的详细信息,bytes.Length等于图片分辨率宽高相乘。
FileStream f = new FileStream(oldFilePath, FileMode.Create);
f.Write(bytes, 0, bytes.Length);
f.Flush();
f.Close();
oldFilePath是指向具体文件路径的,即路径+名称(带后缀);
f.Write中的bytes为Texture的数据信息,从0开始并写入bytes.Length个长度。
这样我们就得到了一张在指定路径下的png图片。
(二)文件夹及文件的操作
DirectoryInfo theFloder = new DirectoryInfo(scanpath);
theFloder就是我们拿到的scanpath路径指向的文件夹。
一般情况我们执行应用程序时创建文件夹的初始化操作
if (!Directory.Exists(scanpath))
{
Directory.CreateDirectory(scanpath);
}//一般写在 void start里。
void load()
{
allTex2d.Clear();
//allTex2d = new List<Texture2D>();
//List<string> filePaths = new List<string>();
string imgtype = "*.BMP|*.JPG|*.GIF|*.PNG";
string[] ImageType = imgtype.Split('|');
//Debug.Log("ImageType.Length" + ImageType.Length);
//DirectoryInfo theFolder = new DirectoryInfo(scanpath);
for (int i = 0; i < ImageType.Length; i++)
{
//Debug.Log(ImageType.Length);
//获取d盘中a文件夹下所有的图片路径
//string[] dirs = Directory.GetFiles(@"g:\\scan\scanimg", ImageType[i]);
string[] dirs = Directory.GetFiles(scanpathh, ImageType[i]);
//dirs[0].na
//Debug.Log("dirsCount" + imgtype.Length);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
//Directory.GetFiles
//Debug.Log(dirs[j]);
}
}
//Debug.Log("filePaths:"+filePaths[0]);
for (int i = 0; i < filePaths.Count; i++)
{
Texture2D tx = new Texture2D(100, 100);
tx.LoadImage(getImageByte(filePaths[i]));
allTex2d.Add(tx);
//Debug.Log("ALLLLL:"+allTex2d[0].name);
}
}
private static byte[] getImageByte(string imagePath)
{
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
return imgByte;
}
load()函数的功能是将指定文件夹里图片加入到一个按名称排序的列表中,这样我们就可以通过操作列表来操作指定的图片(文件)。
string imgtype = "*.BMP|*.JPG|*.GIF|*.PNG";
string[] ImageType = imgtype.Split('|');
以|作为分隔符,ImageType存储了四个字符串。
FileInfo file = theFloder.GetFiles()[GetButtonNum.ii + GetButtonNum.jj];
theFloder.GetFiles是一个列表,可以得到文件夹theFloder里的所有文件信息。
string[] dirs = Directory.GetFiles(scanpathh, ImageType[i]);
dirs将获取到scanpathh路径下所有后缀名为.bmp/.jpg/gif/png的文件的路径。
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
return imgByte;
新建一个流文件files,指向的是imagePath路径下+名称的文件;
通过函数files.Read来向imgByte中写入文件信息。
Texture2D tx = new Texture2D(100, 100);
tx.LoadImage(getImageByte(filePaths[i]));
新建的Texture2D通过函数LoadImage(Bytes)来创建。
(三)canvasTuKu和canvasHuaLang里图片的加载
图库里的图片加载相对简单,我们只需将要加载的20张线稿放入一个数组即可,通过左右按钮来选择加载哪六张图片。
(一)截图操作
截图的基本思路:在绘图区域确定一个矩形,创建一个Texture2D获取这部分像素并生成图片存储在文件夹中。
IEnumerator ScreenSHOT()
{
yield return new WaitForEndOfFrame();
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);
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(ulx, (int)ru.transform.position.y, width, height), 0, 0);
tex.Apply();
byte[] bytes = tex.EncodeToPNG();
string filenameTimeNum = "";
if (ButtonControl.FromHuaCeLoad == false)
{
//Debug.Log("bieaaaa");
string filename = AnimalsName[GetButtonNum.i + GetButtonNum.j];
filenameTimeNum = 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") + AnimalsName[GetButtonNum.i + GetButtonNum.j] + ".png";
}
//如果加载按钮触发,即加载的图片来自相册,执行对图片名称的操作
if (ButtonControl.FromHuaCeLoad == true)
{
//Debug.Log("ScreenShotBefore");
load();
DirectoryInfo theFloder = new DirectoryInfo(scanpathh);
FileInfo NameInfo = theFloder.GetFiles()[GetButtonNum.ii + GetButtonNum.jj];
//Debug.Log("LoadTheimg:" + (GetButtonNum.ii + GetButtonNum.jj));
//Debug.Log("quanming" + NameInfo.Name);
string fileTimeNum = "";
string fileNameInfo = "";
for (int i = 0; i < 18; i++)
{
if ((NameInfo.Name[i] >= 48 || NameInfo.Name[i] <= 57))
{
fileTimeNum += NameInfo.Name[i].ToString();
//fileNameInfo += NameInfo.Name[i].ToString();
//Debug.Log("fileNameInfo:" + fileNameInfo);
}
}
fileNameInfo = NameInfo.Name.Remove(0, 18);
//Debug.Log("filenameinfo:" + fileNameInfo);
filenameTimeNum = 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") + fileNameInfo;
ButtonControl.FromHuaCeLoad = false;
}
//Debug.Log("filename"+filename);
string filenamedd = "hahah";
//string oldFilePathh = "G:/scan/scanimgg/" + filename + ".png";
//string oldFilePath = "G:/scan/scanimg/" + filename + ".png";
string oldFilePathh = scanpathh + "/" + filenameTimeNum;
string oldFilePath = scanpath + "/" + filenameTimeNum;
//string oldFilePath = Application.dataPath + filename + ".png";
//Debug.Log(Application.dataPath);
//G:/ SVN画板 / UnityPaint / Assets
FileStream f = new FileStream(oldFilePath, FileMode.Create);
FileStream ff = new FileStream(oldFilePathh, FileMode.Create);
f.Write(bytes, 0, bytes.Length);
ff.Write(bytes, 0, bytes.Length);
GetComponent<NetworkView>().RPC("ReciveImage", RPCMode.All, filenamedd, filenameTimeNum, bytes);
f.Flush();
f.Close();
ff.Flush();
ff.Close();
System.GC.Collect();
Resources.UnloadUnusedAssets();//卸载未使用的资源
if (ButtonControl.isTuKu2&&!justSave)
{
justPainter.SetActive(false);
TuCeng.SetActive(true);
canvasTuKu.SetActive(true);
ButtonControl.isTuKu2 = false;
}
if(ButtonControl.isAlbum2&&!justSave)
{
justPainter.SetActive(false);
TuCeng.SetActive(true);
canvasHuaLang.SetActive(true);
ButtonControl.isAlbum2 = false;
}
justSave = false;
}
ulx,uly确定截图矩形区域的左上顶点坐标,width和height确定矩形宽高
Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false);
tex.ReadPixels(new Rect(ulx, (int)ru.transform.position.y, width, height), 0, 0);
tex.Apply();
在每次结束了像素操作(Get、Set、Read)后都必须Texture.Apply()。
这样我们就得到了一个截图Texture,接下来把它变成一张图片。
scanpath = Directory.GetParent(Application.dataPath).ToString() + "/scan/scanimg";
用该操作获得Data根目录下的相对路径。
filenameTimeNum = 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") + AnimalsName[GetButtonNum.i + GetButtonNum.j] + ".png";
根据执行该条语句时的时间来为文件命名。
byte[] bytes = tex.EncodeToPNG();
该函数仅工作于ARGB32和RGB24格式。该纹理在纹理导入设置必须具有可读写标识。我们用这个函数来获得Texture的详细信息,bytes.Length等于图片分辨率宽高相乘。
FileStream f = new FileStream(oldFilePath, FileMode.Create);
f.Write(bytes, 0, bytes.Length);
f.Flush();
f.Close();
oldFilePath是指向具体文件路径的,即路径+名称(带后缀);
f.Write中的bytes为Texture的数据信息,从0开始并写入bytes.Length个长度。
这样我们就得到了一张在指定路径下的png图片。
(二)文件夹及文件的操作
DirectoryInfo theFloder = new DirectoryInfo(scanpath);
theFloder就是我们拿到的scanpath路径指向的文件夹。
一般情况我们执行应用程序时创建文件夹的初始化操作
if (!Directory.Exists(scanpath))
{
Directory.CreateDirectory(scanpath);
}//一般写在 void start里。
void load()
{
allTex2d.Clear();
//allTex2d = new List<Texture2D>();
//List<string> filePaths = new List<string>();
string imgtype = "*.BMP|*.JPG|*.GIF|*.PNG";
string[] ImageType = imgtype.Split('|');
//Debug.Log("ImageType.Length" + ImageType.Length);
//DirectoryInfo theFolder = new DirectoryInfo(scanpath);
for (int i = 0; i < ImageType.Length; i++)
{
//Debug.Log(ImageType.Length);
//获取d盘中a文件夹下所有的图片路径
//string[] dirs = Directory.GetFiles(@"g:\\scan\scanimg", ImageType[i]);
string[] dirs = Directory.GetFiles(scanpathh, ImageType[i]);
//dirs[0].na
//Debug.Log("dirsCount" + imgtype.Length);
for (int j = 0; j < dirs.Length; j++)
{
filePaths.Add(dirs[j]);
//Directory.GetFiles
//Debug.Log(dirs[j]);
}
}
//Debug.Log("filePaths:"+filePaths[0]);
for (int i = 0; i < filePaths.Count; i++)
{
Texture2D tx = new Texture2D(100, 100);
tx.LoadImage(getImageByte(filePaths[i]));
allTex2d.Add(tx);
//Debug.Log("ALLLLL:"+allTex2d[0].name);
}
}
private static byte[] getImageByte(string imagePath)
{
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
return imgByte;
}
load()函数的功能是将指定文件夹里图片加入到一个按名称排序的列表中,这样我们就可以通过操作列表来操作指定的图片(文件)。
string imgtype = "*.BMP|*.JPG|*.GIF|*.PNG";
string[] ImageType = imgtype.Split('|');
以|作为分隔符,ImageType存储了四个字符串。
FileInfo file = theFloder.GetFiles()[GetButtonNum.ii + GetButtonNum.jj];
theFloder.GetFiles是一个列表,可以得到文件夹theFloder里的所有文件信息。
string[] dirs = Directory.GetFiles(scanpathh, ImageType[i]);
dirs将获取到scanpathh路径下所有后缀名为.bmp/.jpg/gif/png的文件的路径。
FileStream files = new FileStream(imagePath, FileMode.Open);
byte[] imgByte = new byte[files.Length];
files.Read(imgByte, 0, imgByte.Length);
files.Close();
return imgByte;
新建一个流文件files,指向的是imagePath路径下+名称的文件;
通过函数files.Read来向imgByte中写入文件信息。
Texture2D tx = new Texture2D(100, 100);
tx.LoadImage(getImageByte(filePaths[i]));
新建的Texture2D通过函数LoadImage(Bytes)来创建。
(三)canvasTuKu和canvasHuaLang里图片的加载
图库里的图片加载相对简单,我们只需将要加载的20张线稿放入一个数组即可,通过左右按钮来选择加载哪六张图片。
而画廊里加载的Texture是来自文件夹的,操作上要复杂一些。
值得一提的是:FileInfo.MoveTo(Path+filename)可以将FileInfo剪切到另一个文件夹,但filename不能与Path中的任一文件名称相同,不然会报错且无法执行。