用Unity做簡易的影象處理軟體(二)
阿新 • • 發佈:2018-12-20
這一次添加了水平翻轉、垂直翻轉、順時針旋轉、逆時針旋轉,關閉影象,儲存,退出功能;對RT的建立和銷燬做了一些更改。 介面如下: 關於選擇的C#部分
public void clockwise()
{
clockw = true;
rotate();
}
public void anticlockwise()
{
anclockw = true;
rotate();
}
private void rotate()//旋轉shader更新
{
if (Gamevars. textureisable)
{
rotatematerial.SetInt("_Clockwise", clockw ? 1 : 0);
rotatematerial.SetInt("_AnuiClockwise", anclockw? 1:0);
RenderTexture Disttexture =RenderTexture.GetTemporary(texture.height, texture.width, 0);//因為旋轉之後寬高對調
Graphics.Blit(texture, Disttexture, rotatematerial);
int width = Disttexture.width;
int height = Disttexture.height;
Gamevars.imagewidth = width;
Gamevars.imageheight = height;//更新控制結構體
Viewtexture = new Texture2D(width, height, TextureFormat.ARGB32, false);
RenderTexture. active = Disttexture;
Viewtexture.ReadPixels(new Rect(0, 0, width, height),0, 0);
Viewtexture.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(Disttexture);
texture = Viewtexture;
updateBSC();
image.GetComponent<RectTransform>().sizeDelta = new Vector2(width,height);
Sprite sprite = Sprite.Create(Viewtexture, new Rect(0, 0,width, height), new Vector2(0.5f, 0.5f));
image.sprite = sprite;
Refresh();
}
clockw = false;
anclockw = false;
}
shader部分非常簡單
Shader "myshaders/rotate"
{
Properties
{
_MainTex ("_MainTex", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
int _Clockwise;
int _AnuiClockwise;
struct v2a
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (v2a v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
if(_Clockwise==1){
i.uv=mul(float2x2(0,-1,1,0),i.uv);
}
if(_AnuiClockwise==1){
i.uv=mul(float2x2(0,1,-1,0),i.uv);
}
fixed4 renderTex = tex2D(_MainTex,i.uv);
return fixed4(renderTex);
}
ENDCG
}
}
Fallback Off
}
翻轉的C#部分
public void horizon()
{
overturnX = true;
Overturn();
}
public void vertical()
{
overturnY = true;
Overturn();
}
private void Overturn()//翻轉shader更新
{
if (Gamevars.textureisable)
{
overturnmaterial.SetInt("_Horizon", overturnX ? 1 : 0);
overturnmaterial.SetInt("_Vertical", overturnY ? 1 : 0);
RenderTexture Disttexture = RenderTexture.GetTemporary(texture.width, texture.height, 0);
Graphics.Blit(texture, Disttexture, overturnmaterial);
int width = Disttexture.width;
int height = Disttexture.height;
Viewtexture = new Texture2D(width, height, TextureFormat.ARGB32, false);
RenderTexture.active = Disttexture;
Viewtexture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
Viewtexture.Apply();
RenderTexture.active = null;
RenderTexture.ReleaseTemporary(Disttexture);
texture = Viewtexture;//因為旋轉之後,仍需要其他shader參與
updateBSC();
image.GetComponent<RectTransform>().sizeDelta = new Vector2(Viewtexture.width, Viewtexture.height);
Sprite sprite = Sprite.Create(Viewtexture, new Rect(0, 0, Viewtexture.width, Viewtexture.height), new Vector2(0.5f, 0.5f));
image.sprite = sprite;
Refresh();
}
overturnX = false;
overturnY = false;
}
翻轉的shader部分
Shader "myshaders/overturn"
{
Properties
{
_MainTex ("_MainTex", 2D) = "white" {}
}
SubShader
{
Pass
{
ZTest Always Cull Off ZWrite Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
int _Horizon;
int _Vertical;
struct v2a
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
};
v2f vert (v2a v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
if(_Horizon==1){
i.uv.x=1-i.uv.x;
}
if(_Vertical==1){
i.uv.y=1-i.uv.y;
}
fixed4 renderTex = tex2D(_MainTex,i.uv);
return fixed4(renderTex);
}
ENDCG
}
}
Fallback Off
}
這兩個功能的實現都非常簡單,尤其是shader部分,但是我現在遇到了一個問題,當對一張圖片進行大量操作之後,記憶體佔用量很大 現在我的方法是在關閉影象的時候趁機重新載入一次scene
public void fileclose()
{
if (Gamevars.textureisable)
{
Gamevars.textureisable = false;
selectfile.gameObject.SetActive(true);
Gamevars.size = 1;
size1.text = ((int)(Gamevars.size * 100)).ToString() + "%";
image.color = new Color32(255, 255, 255, 0);
image.transform.position = new Vector3(0, 720, 0);
slider1.value = 1;
slider2.value = 1;
slider3.value = 1;
SceneManager.LoadScene(0);
}
}
關於記憶體佔用問題有什麼好方法的話,還請大佬給我留言 最後儲存程式碼
public void savefile()
{
if (Gamevars.textureisable)
{
SaveFileDialog dialog = new SaveFileDialog();
dialog.Title = "請選擇儲存位置";
dialog.Filter = "影象檔案(*.png)|*.png";
if (dialog.ShowDialog() == DialogResult.OK)
{
byte[] bytes = Viewtexture.EncodeToPNG();
File.WriteAllBytes(dialog.FileName, bytes);
}
}
}
目前只能儲存為PNG格式。。 在下一次,我會新增裁剪功能,和解決記憶體佔用問題。上課去了。。。