先上代码:
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. Mina学习之IoBuffer

    IoBuffer是一个被MINA体系所使用的字节数组.它是ByteBuffer的替代品,Mina不使用NIO的ByteBuffer有两个原因: 1. ByteBuffer没有提供更多有用的api,如f ...

  2. MySQL基础 (DML)

    DML语句             DML操作是指对数据库中表记录的操作,主要包括表记录的插入(insert).更新(update).删除(delete)和查询(select) 1.插入记录 插入一条 ...

  3. 常用的js效验

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Newtonsoft.Json 与 DataTable的相互转换

    1.这里下载:http://www.newtonsoft.com/products/json/ 安装:    解压下载文件,得到Newtonsoft.Json.dll    在项目中添加引用 2.引入 ...

  5. node.js 安装

    http://my.oschina.net/zhangdapeng89/blog/52793 windows 自带的 ims文件安装后 有 安装npm 点击bat文件可自动安装 npm 1安装 nod ...

  6. [React] React Fundamentals: with-addons - ReactLink

    It can be tedious to type out all the boilerplate needed to get the DOM and states in React to synch ...

  7. LCA在线算法ST算法

    求LCA(近期公共祖先)的算法有好多,按在线和离线分为在线算法和离线算法. 离线算法有基于搜索的Tarjan算法较优,而在线算法则是基于dp的ST算法较优. 首先说一下ST算法. 这个算法是基于RMQ ...

  8. 粗谈pcap_next_ex()

      pcap_next_ex(pcap_t* p,struct pcap_pkthdr** pkt_header,const u_char** pkt_data) 功能: 从interface或离线记 ...

  9. QT GUI总结

      QT提供了设计师工具,可以很方便的使用鼠标拖拽的方式绘制界面.绘制完毕后自动生成一个界面的.h文件(如ui_mainwindow.h),其中含有一个自动生成的Ui_MainWindow类,这个类中 ...

  10. 基于HTML5的SLG游戏开发(一):搭建开发环境(1)

    开发环境: 1.操作系统:MacOS 10.8.5 2.本地web服务器:Apache 2.2.24 (Window环境推荐使用WampServer) 3.编码工具:WebStrom 7.0 4.调试 ...