用Unity做简易的图像处理软件(二)

这一次添加了水平翻转、垂直翻转、顺时针旋转、逆时针旋转,关闭图像,保存,退出功能;对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格式。。
在下一次,我会添加裁剪功能,和解决内存占用问题。上课去了。。。

猜你喜欢

转载自blog.csdn.net/qq_33967521/article/details/83990136