Unity用户自定义圆角头像

  前天朋友遇到一个这样的需求,而且比较棘手让我帮忙解决。需求就是棋牌类的游戏,玩家的个人资料中包括自己的头像而且可以浏览相册中的图片或者使用相机拍照设置。关于这个问题我也查阅一些资料,由于涉及安卓部分知识,首先要了解Unity和安卓是如何通信的。

首先看到的是雨松老师的博客:http://www.xuanyusong.com/archives/1480咱们可以一起参考下这篇博客。好了,废话就不多说了,夜已深,开始撸代码吧!  

1 新建空的工程

2,头像显示当然要用图片了,就用UGUI的RawImage吧。

3,准备工作基本上结束了,接下来就是完成浏览相册和拍照上传了。这部分就不详细介绍了网上有很多教程,借助Eclipse完成浏览相册和拍照的逻辑,导出jar包在Unity中调用即可。插件已经导出,稍后会把工程共享给大家!

接下来该调用浏览相册和拍照的功能了,简单的测试,就这样吧!

void OnGUI()
{
        if (GUI.Button(new Rect(10, 10, 100, 100), "Take Photo"))
        {
            OpenCamera();
        }
        if (GUI.Button(new Rect(220, 10, 100, 100), "Photo view"))
        {
            OpenPick();
        }
    if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home))
    {
	  Application.Quit();     }
}

4,既然是圆角头像,那么还要处理圆角了。首先想到的是Shader做个裁剪即可。


是不是很神奇,上一秒还是方的哦!

5,接下来开始测试了,要打包真机测试的,请稍后打包中,,,,

6,哇咔咔,接下来要真机测试了。

对了,上面日志显示两个图片字节数值而且相差很大的,你看到的是对的。由于要考虑网络传输,传输的数据包要尽可能的小,这样才会节省流量和提高效率,第一个值是图片真是的字节数,第二个数值表示压缩后的图片字节数:2119,除以1024也就是2.07kb。这个数据还是可以接受的。

接下来是压缩的实现方法:

using UnityEngine;

using UnityEngine.UI;
using System.Collections;
using System.Threading;

public class TextureTools : MonoBehaviour
{

    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 Texture2D Point(Texture2D tex, int newWidth, int newHeight, bool flipH, bool flipV)
    {
        return ThreadedScale(tex, newWidth, newHeight, false, flipH, flipV);
    }

    public static Texture2D Bilinear(Texture2D tex, int newWidth, int newHeight, bool flipH, bool flipV)
    {
        return ThreadedScale(tex, newWidth, newHeight, true, flipH, flipV);
    }

    private static Texture2D ThreadedScale(Texture2D tex, int newWidth, int newHeight, bool useBilinear, bool flipH, bool flipV)
    {
        texColors = tex.GetPixels();
        newColors = new Color[newWidth * newHeight];
        if (useBilinear)
        {
            ratioX = 1.0f / ((float)newWidth / (tex.width - 1));
            ratioY = 1.0f / ((float)newHeight / (tex.height - 1));
        }
        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 = 0;
        if (mutex == null)
        {
            mutex = new Mutex(false);
        }
        if (cores > 1)
        {
            int i = 0;
            ThreadData threadData;
            for (i = 0; i < cores - 1; i++)
            {
                threadData = new ThreadData(slice * i, slice * (i + 1));
                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(1);
            }
        }
        else
        {
            ThreadData threadData = new ThreadData(0, newHeight);
            if (useBilinear)
            {
                BilinearScale(threadData);
            }
            else
            {
                PointScale(threadData);
            }
        }

        tex.Resize(newWidth, newHeight);
        tex.SetPixels(newColors);
        tex.Apply();
        Texture2D orig = new Texture2D(tex.width, tex.height);
        if (flipV)
        {
            int xN = tex.width;
            int yN = tex.width;

            for (int i = 0; i < xN; i++)
            {
                for (int j = 0; j < yN; j++)
                {
                    // tex.SetPixel(xN - i - 1, j, orig.GetPixel(i, j));
                    orig.SetPixel(i, yN - j - 1, tex.GetPixel(i, j));
                }
            }
            orig.Apply();

        }
        else if (flipH)
        {
            int xN = tex.width;
            int yN = tex.width;

            for (int i = 0; i < xN; i++)
            {
                for (int j = 0; j < yN; j++)
                {
                    // tex.SetPixel(xN - i - 1, j, orig.GetPixel(i, j));
                    orig.SetPixel(xN - i - 1, j, tex.GetPixel(i, j));
                }
            }
            orig.Apply();

        }
        else
        {
            orig = tex;
        }
        return orig;
    }

    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 + 1) * w;
            var yw = y * w2;

            for (var x = 0; 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 + 1], xLerp),
                                                       ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor + 1], 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 = 0; 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);
    }

}

OK,实用的小功能已做完,大家如果有问题可以给我留言,猿类要技术共享哦!

传送门:git@github.com:wuzhangwuzhang/UnityHeadIconSet.git

时间: 2024-10-10 19:14:00

Unity用户自定义圆角头像的相关文章

unity之圆角头像实现

重写了一个image组件,将精灵拖进去可调整圆角的大小和平滑度,我写的这个只支持正方形图片,矩形会比较麻烦,暂时还没想到方法 实现思路: 1.如下图,image画图原理就是在一个方框中画三角形,然后形成图片,红线代表方框的坐标系,蓝色代表图片的坐标系,也就是你在这个方框的某个位置上画图片的哪个部位,例如蓝色的(0,0)点,假如image宽度,高度都为2,也就是在黑框的(-1,-1)画一个(0,0)点. 2.如果想要圆角就很简单了,就是在角上多画几个间距相等的点,点越多平滑度越高,例如我图中左上角

【android】 圆角头像

I:画圆角: 1 private void roundImg(ImageView iv){ 2 3 /**本地资源*/ 4 5 InputStream is = getResources().openRawResource(R.drawable.icon); 6 7 Bitmap bitmap = BitmapFactory.decodeStream(is); 8 9 /**网络资源*/ 10 11 //FileInputStream fis = new FileInputStream(url)

Android Demo---如何敲出圆角的Button+圆角头像

经常玩儿App的小伙伴都知道,APP上面有很多按钮都是圆角的,圆形给人感觉饱满,富有张力,不知道设计圆角按钮的小伙伴是不是和小编有着相同的想法`(*∩_∩*)′,听小编公司开发IOS的小伙伴说,他们里面直接有圆角的button,但是对于开发Android的小伙伴就不一样了,里面没有直接的圆角button可以供我们使用,在xml里面布局一个button,还不是圆角的,怎么办nie,方法总比困难多,我们成长的机会又来了,最近在小编的项目中,需要用到圆角的button,还需要用到圆角的头像,经过半天捣

圆角头像----CSS3特效

w3c:http://www.w3school.com.cn/cssref/pr_border-radius.asp 定义和用法 border-radius 属性是一个简写属性,用于设置四个 border-*-radius 属性. 提示:该属性允许您为元素添加圆角边框! 属性border-radius:50px; 这时候头像的外框就有圆角效果 div { border:2px solid; border-radius:50%; }

小程序圆角头像

<open-data type="userAvatarUrl" class="head-img"></open-data> .head-img {   width: 140rpx;   height: 140rpx;   border-radius: 50%;   margin-top: 40rpx;   display: block;   overflow: hidden; } 原文地址:https://www.cnblogs.com/xy

给头像设置圆角的卡顿解决

加入在tableView的每个cell里都有一个圆角头像,因为在layer.corner...开销过大,所以会造成卡顿,可以通过贝塞尔曲线进行绘制. // 如下所示 // Get your image somehow UIImage *image = [UIImage imageNamed:@"image.jpg"]; // Begin a new image that will be the new image with the rounded corners // (here wi

IOS 设置圆角用户头像

在App中有一个常见的功能,从系统相册或者打开照相机得到一张图片,然后作为用户的头像.从相册中选取的图片明明都是矩形的图片,但是展示到界面上却变成圆形图片,这个神奇的效果是如何实现的呢? 请大家跟着下面的步骤,去实现选取并展示圆角头像的功能吧! 一.设置显示头像的圆角图片 1. 显示用户头像用UIImageView实现,添加默认图片后效果如下图所示,头像显示为矩形图片. 代码实现: // ViewController.m // SetUserImage // // Created by jere

圆形头像CircleImageView和Cardview使用

效果: 圆形头像在我们的日常使用的app中很常见,因为圆形的头像比较美观. 使用圆形图片的方法可能有我们直接将图片裁剪成圆形再在app中使用, 还有就是使用自定义View对我们设置的任何图片自动裁剪成圆形. 这里使用github上CircleImageView github:https://github.com/hdodenhof/CircleImageView CardView顾名思义卡片式的View, CardView继承的是FrameLayout,所以摆放内部控件的时候需要注意一下 可以设

MonoTouch - iOS 使用 UIImagePickerController 打开图片库和相机选择图片修改头像

Application tried to present modally an active controller <UIImagePickerController: 0x7b6ff400> 1,AddGestureRecognizer为图片视图添加事件 //圆角头像 _avatarView = new UIImageView(new RectangleF(_blockSpace, _blockSpace, 2 * _avatarRadius, 2 * _avatarRadius)); UII