先上代码:
1 using System.Threading;
using UnityEngine;
using System.IO;
using System.Collections; public class TextureUtility
{
public class ThreadData
{
public int start;
public int end;
public ThreadData (int s, int e) {
start = s;
end = e;
}
} private static Color[] texColors;
private static Color[] newColors;
private static int w;
private static float ratioX;
private static float ratioY;
private static int w2;
private static int finishCount;
private static Mutex mutex; public static void ScalePoint (Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale (tex, newWidth, newHeight, false);
} public static void ScaleBilinear (Texture2D tex, int newWidth, int newHeight)
{
ThreadedScale (tex, newWidth, newHeight, true);
} private static void ThreadedScale (Texture2D tex, int newWidth, int newHeight, bool useBilinear)
{
texColors = tex.GetPixels();
newColors = new Color[newWidth * newHeight];
if (useBilinear)
{
ratioX = 1.0f / ((float)newWidth / (tex.width-));
ratioY = 1.0f / ((float)newHeight / (tex.height-));
}
else {
ratioX = ((float)tex.width) / newWidth;
ratioY = ((float)tex.height) / newHeight;
}
w = tex.width;
w2 = newWidth;
var cores = Mathf.Min(SystemInfo.processorCount, newHeight);
var slice = newHeight/cores; finishCount = ;
if (mutex == null) {
mutex = new Mutex(false);
}
if (cores > )
{
int i = ;
ThreadData threadData;
for (i = ; i < cores-; i++) {
threadData = new ThreadData(slice * i, slice * (i + ));
ParameterizedThreadStart ts = useBilinear ? new ParameterizedThreadStart(BilinearScale) : new ParameterizedThreadStart(PointScale);
Thread thread = new Thread(ts);
thread.Start(threadData);
}
threadData = new ThreadData(slice*i, newHeight);
if (useBilinear)
{
BilinearScale(threadData);
}
else
{
PointScale(threadData);
}
while (finishCount < cores)
{
Thread.Sleep();
}
}
else
{
ThreadData threadData = new ThreadData(, newHeight);
if (useBilinear)
{
BilinearScale(threadData);
}
else
{
PointScale(threadData);
}
} tex.Resize(newWidth, newHeight);
tex.SetPixels(newColors);
tex.Apply();
} public static void BilinearScale (System.Object obj)
{
ThreadData threadData = (ThreadData) obj;
for (var y = threadData.start; y < threadData.end; y++)
{
int yFloor = (int)Mathf.Floor(y * ratioY);
var y1 = yFloor * w;
var y2 = (yFloor+) * w;
var yw = y * w2; for (var x = ; x < w2; x++) {
int xFloor = (int)Mathf.Floor(x * ratioX);
var xLerp = x * ratioX-xFloor;
newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor+], xLerp),
ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor+], xLerp),
y*ratioY-yFloor);
}
} mutex.WaitOne();
finishCount++;
mutex.ReleaseMutex();
} public static void PointScale (System.Object obj)
{
ThreadData threadData = (ThreadData) obj;
for (var y = threadData.start; y < threadData.end; y++)
{
var thisY = (int)(ratioY * y) * w;
var yw = y * w2;
for (var x = ; x < w2; x++) {
newColors[yw + x] = texColors[(int)(thisY + ratioX*x)];
}
} mutex.WaitOne();
finishCount++;
mutex.ReleaseMutex();
} private static Color ColorLerpUnclamped (Color c1, Color c2, float value)
{
return new Color (c1.r + (c2.r - c1.r)*value,
c1.g + (c2.g - c1.g)*value,
c1.b + (c2.b - c1.b)*value,
c1.a + (c2.a - c1.a)*value);
} public static Texture2D LoadTexture(string filePath) {
Texture2D tex = null;
byte[] fileData; if (File.Exists(filePath)) {
fileData = File.ReadAllBytes(filePath);
tex = new Texture2D(, ,TextureFormat.ARGB32,false);
tex.LoadImage(fileData);
}
return tex;
} // Save ScreenShot public static void SaveScreenShotAsync(string path, Vector2 size)
{
SWMain.sharedSWMain.StartCoroutine(TextureUtility.SaveScreenShot(path, size));
} public static void SaveScreenShotAsync(string path, Rect rect, Vector2 size)
{
SWMain.sharedSWMain.StartCoroutine(TextureUtility.SaveScreenShot(path, rect, size));
} public static IEnumerator SaveScreenShot(string path, Vector2 size)
{
Rect rect = new Rect (, , Screen.width, Screen.height);
yield return SWMain.sharedSWMain.StartCoroutine(TextureUtility.SaveScreenShot(path,rect, size));
} public static IEnumerator SaveScreenShot(string path, Rect rect, Vector2 size = default(Vector2))
{
// We should only read the screen bufferafter rendering is complete
yield return new WaitForEndOfFrame();
// 要保存图片的大小
Texture2D tex = new Texture2D ((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
// 截取的区域
tex.ReadPixels(rect, , );
tex.Apply();
// 把图片数据转换为byte数组
if (size != default(Vector2))
{
ScaleBilinear(tex, (int)size.x, (int)size.y);
} byte[] buffer = tex.EncodeToJPG ();
Object.Destroy(tex);
// 然后保存为图片
File.WriteAllBytes(path, buffer);
} public static Texture2D Copy(Texture2D tex)
{
return new Texture2D(tex.width, tex.height, tex.format, false);
} /// <summary>
/// Applies sepia effect to the texture.
/// </summary>
/// <param name="tex"> Texture to process.</param>
public static Texture2D SetSepia(Texture2D tex)
{
Texture2D t = Copy(tex);
Color[] colors = tex.GetPixels(); for (int i = ; i < colors.Length; i++)
{
float alpha = colors[i].a;
float grayScale = ((colors[i].r * .299f) + (colors[i].g * .587f) + (colors[i].b * .114f));
Color c = new Color(grayScale, grayScale, grayScale);
colors[i] = new Color(c.r * , c.g * 0.95f, c.b * 0.82f, alpha);
}
t.SetPixels(colors);
t.Apply();
return t;
} /// <summary>
/// Applies grayscale effect to the texture and changes colors to grayscale.
/// </summary>
/// <param name="tex"> Texture to process.</param>
public static Texture2D SetGrayscale(Texture2D tex)
{
Texture2D t = Copy(tex); Color[] colors = tex.GetPixels();
for (int i = ; i < colors.Length; i++)
{
float val = (colors [i].r + colors [i].g + colors [i].b) / ;
colors [i] = new Color(val, val, val);
}
t.SetPixels(colors);
t.Apply();
return t;
} /// <summary>
/// Pixelates the texture.
/// </summary>
/// <param name="tex"> Texture to process.</param>
/// <param name="size"> Size of the pixel.</param>
public static Texture2D SetPixelate(Texture2D tex, int size)
{
Texture2D t = Copy(tex);
Rect rectangle = new Rect(, , tex.width, tex.height);
for (int xx = (int)rectangle.x; xx < rectangle.x + rectangle.width && xx < tex.width; xx += size)
{
for (int yy = (int)rectangle.y; yy < rectangle.y + rectangle.height && yy < tex.height; yy += size)
{
int offsetX = size / ;
int offsetY = size / ;
while (xx + offsetX >= tex.width) offsetX--;
while (yy + offsetY >= tex.height) offsetY--;
Color pixel = tex.GetPixel(xx + offsetX, yy + offsetY);
for (int x = xx; x < xx + size && x < tex.width; x++)
for (int y = yy; y < yy + size && y < tex.height; y++)
t.SetPixel(x, y, pixel);
}
} t.Apply();
return t;
} /// <summary>
/// Inverts colors of the texture.
/// </summary>
/// <param name="tex"> Texture to process.</param>
public static Texture2D SetNegative(Texture2D tex)
{
Texture2D t = Copy(tex);
Color[] colors = tex.GetPixels();
Color pixel; for (int i = ; i < colors.Length; i++)
{
pixel = colors[i];
colors[i] = new Color( - pixel.r, - pixel.g, - pixel.b);
}
t.SetPixels(colors);
t.Apply();
return t;
} /// <summary>
/// Sets the foggy effect.雾化效果
/// </summary>
/// <returns>texture processed.</returns>
/// <param name="tex">texture to process.</param>
public static Texture2D SetFoggy(Texture2D tex)
{
Texture2D t = Copy(tex);
Color pixel; for (int x = ; x < tex.width - ; x++)
for (int y = ; y < tex.height - ; y++)
{
int k = UnityEngine.Random.Range(, );
//像素块大小
int dx = x + k % ;
int dy = y + k % ;
if (dx >= tex.width)
dx = tex.width - ;
if (dy >= tex.height)
dy = tex.height - ;
pixel = tex.GetPixel(dx, dy);
t.SetPixel(x, y, pixel);
} t.Apply(); return t;
} /// <summary>
/// Sets the soft effect.柔化效果
/// </summary>
/// <returns>texture processed.</returns>
/// <param name="tex">texture to process.</param>
public static Texture2D SetSoft(Texture2D tex)
{
Texture2D t = Copy(tex);
int[] Gauss = { , , , , , , , , };
for (int x = ; x < tex.width - ; x++)
for (int y = ; y < tex.height - ; y++)
{
float r = , g = , b = ;
int Index = ;
for (int col = -; col <= ; col++)
for (int row = -; row <= ; row++)
{
Color pixel = tex.GetPixel(x + row, y + col);
r += pixel.r * Gauss[Index];
g += pixel.g * Gauss[Index];
b += pixel.b * Gauss[Index];
Index++;
}
r /= ;
g /= ;
b /= ;
//处理颜色值溢出
r = r > ? : r;
r = r < ? : r;
g = g > ? : g;
g = g < ? : g;
b = b > ? : b;
b = b < ? : b;
t.SetPixel(x - , y - , new Color(r, g, b));
} t.Apply(); return t;
} /// <summary>
/// Sets the sharp.锐化效果
/// </summary>
/// <returns>The sharp.</returns>
/// <param name="tex">Tex.</param>
public static Texture2D SetSharp(Texture2D tex)
{
Texture2D t = Copy(tex);
Color pixel;
//拉普拉斯模板
int[] Laplacian ={ -, -, -, -, , -, -, -, - };
for (int x = ; x < tex.width - ; x++)
for (int y = ; y < tex.height - ; y++)
{
float r = , g = , b = ;
int index = ;
for (int col = -; col <= ; col++)
for (int row = -; row <= ; row++)
{
pixel = tex.GetPixel(x + row, y + col); r += pixel.r * Laplacian[index];
g += pixel.g * Laplacian[index];
b += pixel.b * Laplacian[index];
index++;
}
//处理颜色值溢出
r = r > ? : r;
r = r < ? : r;
g = g > ? : g;
g = g < ? : g;
b = b > ? : b;
b = b < ? : b;
t.SetPixel(x - , y - , new Color(r, g, b));
} t.Apply();
return t;
} /// <summary>
/// Sets the relief.浮雕效果
/// </summary>
/// <returns>The relief.</returns>
/// <param name="tex">Tex.</param>
public static Texture2D SetRelief(Texture2D tex)
{
Texture2D t = Copy(tex); for (int x = ; x < tex.width - ; x++)
{
for (int y = ; y < tex.height - ; y++)
{
float r = , g = , b = ;
Color pixel1 = tex.GetPixel(x, y);
Color pixel2 = tex.GetPixel(x + , y + );
r = Mathf.Abs(pixel1.r - pixel2.r + 0.5f);
g = Mathf.Abs(pixel1.g - pixel2.g + 0.5f);
b = Mathf.Abs(pixel1.b - pixel2.b + 0.5f);
if (r > )
r = ;
if (r < )
r = ;
if (g > )
g = ;
if (g < )
g = ;
if (b > )
b = ;
if (b < )
b = ;
t.SetPixel(x, y, new Color(r, g, b));
}
} t.Apply();
return t;
} }
如何调用:
1. 压缩图片:
  TextureUtility.ScalePoint(Texture2D tex, int newWidth, int newHeight),第一个参数是要传入的Texture2D, 第二个参数是新的图片的宽度,第三个参数则是新的图片的高度。也可以调用TextureUtility.ScaleBilinear(Texture2D tex, int newWidth, int newHeight)。
2. 截屏:
yield return StartCoroutine(TextureUtility.SaveScreenShot(string path, Vector2 size, Vector2 size = default(Vector2)))
或者调用异步方法TextureUtility.SaveScreenShotAsync(string path, Rect rect, Vector2 size)
3. 图片滤镜:
如灰阶滤镜:TextureUtility.SetGrayscale(Texture2D tex);
底片滤镜:TextureUtility.SetNegative(Texture2D tex)等。

Unity图片处理类,包括压缩、截屏和滤镜的更多相关文章

  1. 压缩图片工具类,压缩100KB以内拿走直接用

    最近遇到自拍上传图片过大问题,很烦恼,所以自己写了一个压缩图片的工具类使用,自测效果很不错,可以压缩到KB以内,像素还可以分辨清晰 下面Java代码奉上: import lombok.extern.s ...

  2. java图片压缩工具类(指定压缩大小)

    1:先导入依赖 <!--thumbnailator图片处理--> <dependency> <groupId>net.coobird</groupId> ...

  3. 一个类实现Java截屏并保存到指定文件夹

    不知小伙伴们有没有遇到过使用java来截屏的需求,截屏后保存到指定的目录,在桌面上没有任何体现,完全不知道已经被截屏了.至于截屏后怎么做,可能有的老铁只是好奇想知道某人在干啥?也有的老铁可能想进行文字 ...

  4. iOS开发 代码 或 <Home+Power>截屏

      1. 截屏的两种简单方法, 注意这两种截图方法,都必须在视图完全加载完成后才能截图,即在 viewDidAppear 方法之后截屏,否则无法得到想要的截屏效果 (1) 利用绘图方法 renderI ...

  5. MacOS 如何截屏

    在Mac OS X下有很强大的截屏功能,它不仅仅是对屏幕的全屏COPY,而是包括很多细节在里面,就从这点来看,已经比过所有版本的Windows了. 下面我来向大家详细介绍一下: 对全屏的截图我们可以通 ...

  6. Mac下的截屏功能

    全屏截图 对全屏的截图我们可以通过按 苹果键(花键)+Shift键+3来执行,之后伴随着清脆的一声提示音后,在桌面上就会生成一个图片文件,这就是刚刚截屏的图片了,默认文件类型是PNG的. 自定义截图 ...

  7. IOS第17天(2,Quartz2D图片剪裁变圆行图,和截屏图片)

    **** #import "HMViewController.h" #import "UIImage+Tool.h" @interface HMViewCont ...

  8. Java 截屏工具类

    PrintScreenUtils.java package javax.utils; import java.awt.AWTException; import java.awt.Dimension; ...

  9. Unity通过指定摄像机截屏

    简介 介于照抄网上之前的截图教程,然后在实际应用过程中出现了一些小小的问题,修正了一下下,特此分享一下 PS:代码在后面 原理 原理很简单,就是将一个相机的内容渲染到一个贴图上,然后将贴图保存为图片 ...

随机推荐

  1. 手把手教你mysql(十)索引

    手把手教你mysql(十)索引 一:索引的引入 索引定义:索引是由数据库表中一列或者多列组合而成,其作用是提高对表中数据的查询速度. 类似于图书的目录,方便快速定位,寻找指定的内容,如一本1000页的 ...

  2. MYSQL ERROR CODE 错误编号的意义

    mysql error code(备忘) 转1005:创建表失败 1006:创建数据库失败 1007:数据库已存在,创建数据库失败 1008:数据库不存在,删除数据库失败 1009:不能删除数据库文件 ...

  3. boost------asio库的使用2(Boost程序库完全开发指南)读书笔记

    网络通信 asio库支持TCP.UDP.ICMP通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好地封装了原始的Berkeley Socket Api,展现 ...

  4. 坚持c++,真正掌握c++(2)

    在c++中对c中的输入输出进行了扩展,採用了面向对象的设计方法设计了c++中的输入输出(IO).输入输出依照操作的对象分类可分为:1. 标准IO(对计算机的键盘或者显示器进行读写操作).2. 文件IO ...

  5. 小猪的Android入门之路 Day 3 - part 3

    小猪的Android入门之路 Day 3 - part 3 各种UI组件的学习 Part 3 本节引言: 在前面两个部分中我们对Android中一些比較经常使用的基本组件进行了一个了解, part 1 ...

  6. kswapd0、kjournald、pdflush、kblocked、migration进程含义 转

    kswapd0.kjournald.pdflush.kblocked.migration进程含义 1.kswapd0 Linux uses kswapd for virtual memory mana ...

  7. I/O体系结构和设备驱动程序

    http://blog.csdn.net/kafeiflynn/article/category/789844

  8. [转] 使用NVM快速搭建NODE开发环境

    export NVM_NODEJS_ORG_MIRROR=https://npm.taobao.org/mirrors/node 本文主要介绍最近自己碰到的几个坑以及搜索到的相应解决方案: 如何快速搭 ...

  9. 2 - SQL Server 2008 之 使用SQL语句为现有表添加约束条件

    上一节讲的是直接在创建表的时候添加条件约束,但是有时候是在表格创建完毕之后,再添加条件约束的,那么这个又该如何实现? 其实,跟上一节所写的SQL代码,很多是相同的,只是使用了修改表的ALTER关键字及 ...

  10. ado.net与各种orm操作数据方式的比较

    ADO.NET与ORM的比较(1):ADO.NET实现CRUD http://zhoufoxcn.blog.51cto.com/792419/283952 ADO.NET与ORM的比较(2):NHib ...