摘要: 传统web请求,是显式的向服务器发送http Request,拿到Response后显示在浏览器页面上。这种被动的交互方式不能满足对信息即时性要求高的应用,譬如聊天室、股票交易行情、在线游戏等。Ajax轮询虽然可以解决这个问题,但是会带来增加服务器负担已经带宽浪费,并且这种实现方式不够优雅。而Comet技术就是为此而生的。 本文只探讨基于浏览器的web端服务器推技术。服务器推技术在现实应用中有一些解决方案,主要分两类:一类是需要浏览器额外安装插件,基于套接口传送信息或者是基于RMI、CORBA进行远程调用,另一类则无需浏览器安装任何插件,就是本文着重讲的HTTP长连接技术:Coment。Alex Russell(Dojo Toolkit 的项目 Lead)称这种基于 HTTP 长连接、无须在浏览器端安装插件的“服务器推”技术为“Comet”。 阅读全文
posted @ 2013-09-12 17:03 夜の魔王 阅读(3684) 评论(24) 推荐(3) 编辑

一、需求概述

多人聊天(群组,讨论组,聊天室,以下统称: “群组” )生成一个拼接头像,需要把最先加入群组的几个人(最多4个人,以下简称:头部用户A、B、C、D)的头像拼凑成在一起。

群组创建后,A、B、C、D其中任何一个修改了自己的头像,需要 "异步" 更新群组头像。

以上是简单的需求描述。

本文使用.net core实现了N张图片拼接算法。

完整代码点击:https://github.com/night-king/ImageMerge

 

二、方案实现探讨

本需求可以在服务端实现,也可以在客户端实现。

(1)服务端实现:

         群组创建时,下载A、B、C、D的头像,然后合并即可;

         头部用户修改头像后,后台任务刷新群组头像。

(2)客户端实现:客户端包括iOS,Android,React,Web。

         情况有些复杂,所以最后决定直接采用服务端实现。

 

 Github上搜索无果,只能自己动手完成了。

 

先看效果:

采用四位Github大神头像作为源图片:

    

结果如下:

 

 

三、解决方案

群组2个用户,3个用户,4个以及以上用户头像不一样,总结如下:

    /// <summary>
    /// 合并布局枚举
    /// </summary>
    public enum Merge2LayoutEnum
    {
        /// <summary>
        /// 2张图片,上下各1个长方形
        ///  ———————————————————
        /// |                  |
        /// |        R1        |
        /// |                  |
        ///  ———————————————————
        /// |                  |
        /// |        R2        |
        /// |                  |
        ///  ———————————————————
        /// </summary>
        Merge2R1 = 1,

        /// <summary>
        /// 2张图片,左右各1个长方形
        ///  ———————————————————
        /// |         |        |
        /// |         |        |
        /// |         |        |
        /// |    R1   |   R2   |
        /// |         |        |
        /// |         |        |
        /// |         |        |
        ///  ———————————————————
        /// </summary>
        Merge2R2 = 2
    }

    public enum Merge3LayoutEnum
    {

        /// <summary>
        /// 3张图片, 上面一个长方形,下面2个正方形并排
        ///  ———————————————————
        /// |                  |
        /// |         R1       |
        /// |                  |
        ///  ———————————————————
        /// |         |        |
        /// |    S1   |   S2   |
        /// |         |        |
        ///  ———————————————————
        /// </summary>
        Merge1R2S1 = 3,

        /// <summary>
        /// 3张图片,上面2个正方形并排,下面一个长方形
        ///  ———————————————————
        /// |         |        |
        /// |    S1   |   S2   |
        /// |         |        |
        ///  ———————————————————
        /// |                  |
        /// |         R1       |
        /// |                  |
        /// ———————————————————
        /// </summary>
        Merge1R2S2 = 4,


        /// <summary>
        /// 3张图片,上面2个正方形并排,下面一个长方形
        ///  ———————————————————
        /// |         |        |
        /// |         |    S1  |
        /// |         |        |
        /// |    R1   |—————————
        /// |         |        |
        /// |         |    S2  |
        /// |         |        |
        ///  ———————————————————
        /// </summary>
        Merge1R2S3 = 5,


        /// <summary>
        /// 3张图片,上面2个正方形并排,下面一个长方形
        ///  ———————————————————
        /// |         |        |
        /// |    S2   |        |
        /// |         |        |
        /// |—————————|    R1  |
        /// |         |        |
        /// |    S2   |        |
        /// |         |        |
        ///  ———————————————————
        /// </summary>
        Merge1R2S4 = 6
    }

    public enum Merge4LayoutEnum
    {
        /// <summary>
        /// 4张图片,上面一个长方形,下面2个正方形并排
        ///  ———————————————————
        /// |         |        |
        /// |    S1   |   S2   |
        /// |         |        |
        ///  ———————————————————
        /// |         |        |
        /// |    S3   |   S4   |
        /// |         |        |
        ///  ———————————————————
        /// </summary>
        Merge4S = 7

    }

 

以下是2张图片实现代码:

        /// <summary>
        /// 合并2张图片
        /// </summary>
        /// <param name="image1"></param>
        /// <param name="image2"></param>
        /// <param name="layout"></param>
        /// <returns></returns>
        public static Image Merge2Images(Image image1, Image image2, Merge2LayoutEnum layout = Merge2LayoutEnum.Merge2R1, int size = 250)
        {
            var width = size;
            var height = size;
            var pf = PixelFormat.Format32bppArgb;
            using (var bg = new Bitmap(width, height, pf))
            {
                using (var g = Graphics.FromImage(bg))
                {
                    g.FillRectangle((Brush)Brushes.White, 0, 0, width, height);//全幅背景为白色
                    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
                    switch (layout)
                    {
                        /// <summary>
                        /// 2张图片,上下各1个长方形
                        ///  ———————————————————
                        /// |                  |
                        /// |        R1        |
                        /// |                  |
                        ///  ———————————————————
                        /// |                  |
                        /// |        R2        |
                        /// |                  |
                        ///  ———————————————————
                        /// </summary>
                        case Merge2LayoutEnum.Merge2R1:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newHeight = height / 2;// =125
                                    var newWidth = width;//       =250
                                    var srcWidth = img1.Width;//  =250
                                    var srcHeight = img1.Height * newHeight / newWidth;//=250*125/250=125
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newHeight = height / 2;// =125
                                    var newWidth = width;     //  =250
                                    var srcWidth = img2.Width;//  =250
                                    var srcHeight = img2.Height * newHeight / newWidth;//=250*125/250=125
                                    g.DrawImage(img2, new Rectangle(0, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                        /// <summary>
                        /// 2张图片,左右各1个长方形
                        ///  ———————————————————
                        /// |         |        |
                        /// |         |        |
                        /// |         |        |
                        /// |    R1   |   R2   |
                        /// |         |        |
                        /// |         |        |
                        /// |         |        |
                        ///  ———————————————————
                        /// </summary>
                        case Merge2LayoutEnum.Merge2R2:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newWidth = width / 2;//   =125
                                    var newHeight = height;  //   =250
                                    var srcWidth = img1.Width * newWidth / newHeight;//=250*125/250=125
                                    var srcHeight = img1.Height;//  =250
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newWidth = width / 2;//   =125
                                    var newHeight = height;  //   =250
                                    var srcWidth = img2.Width * newWidth / newHeight;//=500*125/250=250
                                    var srcHeight = img2.Height;//  =500
                                    g.DrawImage(img2, new Rectangle(width / 2, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                    }
                    g.Save();
                    image1.Dispose();
                    image2.Dispose();
                }

                using (var ms = new MemoryStream())
                {
                    bg.Save(ms, ImageFormat.Png);
                    var buffers = ms.ToArray();
                    return ConvertToImage(buffers);
                }
            }
        }
View Code

 

以下是三种图片的生成算法

        /// <summary>
        /// 合并3张图片
        /// </summary>
        /// <param name="image1"></param>
        /// <param name="image2"></param>
        /// <param name="image3"></param>
        /// <param name="layout"></param>
        /// <returns></returns>
        public static Image Merge3Images(Image image1, Image image2, Image image3, Merge3LayoutEnum layout = Merge3LayoutEnum.Merge1R2S1, int size = 250)
        {
            var width = size;
            var height = size;
            var pf = PixelFormat.Format32bppArgb;
            using (var bg = new Bitmap(width, height, pf))
            {
                using (var g = Graphics.FromImage(bg))
                {
                    g.FillRectangle((Brush)Brushes.White, 0, 0, width, height);//全幅背景为白色
                    switch (layout)
                    {
                        /// <summary>
                        /// 3张图片, 上面一个长方形,下面2个正方形并排
                        ///  ———————————————————
                        /// |                  |
                        /// |         R1       |
                        /// |                  |
                        ///  ———————————————————
                        /// |         |        |
                        /// |    S1   |   S2   |
                        /// |         |        |
                        ///  ———————————————————
                        /// </summary>
                        case Merge3LayoutEnum.Merge1R2S1:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newHeight = height / 2;// =125
                                    var newWidth = width;//       =250
                                    var srcWidth = img1.Width;//  =250
                                    var srcHeight = img1.Height * newHeight / newWidth;//=250*125/250=125
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newHeight = height / 2;//  =125
                                    var newWidth = width / 2;  //  =125
                                    var srcWidth = img2.Width; //  =250
                                    var srcHeight = img2.Height;// =250
                                    g.DrawImage(img2, new Rectangle(0, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img3 = ZoomToSqure(image3, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img3.Width; //   =250
                                    var srcHeight = img3.Height;//  =250
                                    g.DrawImage(img3, new Rectangle(width / 2, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                        /// <summary>
                        /// 3张图片,上面2个正方形并排,下面一个长方形
                        ///  ———————————————————
                        /// |         |        |
                        /// |    S1   |   S2   |
                        /// |         |        |
                        ///  ———————————————————
                        /// |                  |
                        /// |         R1       |
                        /// |                  |
                        /// ———————————————————
                        /// </summary>
                        case Merge3LayoutEnum.Merge1R2S2:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newHeight = height / 2;//  =125
                                    var newWidth = width / 2;  //  =125
                                    var srcWidth = img1.Width; //  =250
                                    var srcHeight = img1.Height;// =250
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img2.Width; //   =250
                                    var srcHeight = img2.Height;//  =250
                                    g.DrawImage(img2, new Rectangle(width / 2, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img3 = ZoomToSqure(image3, size))
                                {
                                    var newHeight = height / 2;// =125
                                    var newWidth = width;//       =250
                                    var srcWidth = img3.Width;//  =250
                                    var srcHeight = img3.Height * newHeight / newWidth;//=250*125/250=125
                                    g.DrawImage(img3, new Rectangle(0, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                        /// <summary>
                        /// 3张图片,上面2个正方形并排,下面一个长方形
                        ///  ———————————————————
                        /// |         |        |
                        /// |         |    S1  |
                        /// |         |        |
                        /// |    R1   |—————————
                        /// |         |        |
                        /// |         |    S2  |
                        /// |         |        |
                        ///  ———————————————————
                        /// </summary>
                        case Merge3LayoutEnum.Merge1R2S3:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newHeight = height;//     =250
                                    var newWidth = width / 2;//   =125
                                    var srcHeight = img1.Height;//=250
                                    var srcWidth = img1.Width * newWidth / newHeight;//  =250*125/250=125;
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newHeight = height / 2;//  =125
                                    var newWidth = width / 2;  //  =125
                                    var srcWidth = img2.Width; //  =250
                                    var srcHeight = img2.Height;// = 250
                                    g.DrawImage(img2, new Rectangle(width / 2, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img3 = ZoomToSqure(image3, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img3.Width; //   =250
                                    var srcHeight = img3.Height;//  =250
                                    g.DrawImage(img3, new Rectangle(width / 2, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                        /// <summary>
                        /// 3张图片,上面2个正方形并排,下面一个长方形
                        ///  ———————————————————
                        /// |         |        |
                        /// |    S2   |        |
                        /// |         |        |
                        /// |—————————|    R1  |
                        /// |         |        |
                        /// |    S2   |        |
                        /// |         |        |
                        ///  ———————————————————
                        /// </summary>
                        case Merge3LayoutEnum.Merge1R2S4:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newHeight = height / 2;//  =125
                                    var newWidth = width / 2;  //  =125
                                    var srcWidth = img1.Width; //  =250
                                    var srcHeight = img1.Height;// =250
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img2.Width; //   =250
                                    var srcHeight = img2.Height;//  =250
                                    g.DrawImage(img2, new Rectangle(0, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img3 = ZoomToSqure(image3, size))
                                {
                                    var newHeight = height;//     =250
                                    var newWidth = width / 2;//   =125
                                    var srcHeight = img3.Height;//=250
                                    var srcWidth = img3.Width * newWidth / newHeight;//  =250*125/250=125;
                                    g.DrawImage(img3, new Rectangle(width / 2, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                    }
                    g.Save();
                    image1.Dispose();
                    image2.Dispose();
                    image3.Dispose();
                }
                using (var ms = new MemoryStream())
                {
                    bg.Save(ms, ImageFormat.Png);
                    var buffers = ms.ToArray();
                    return ConvertToImage(buffers);
                }
            }
        }
View Code

 

以下是4张图片的生成是算法:

        /// <summary>
        /// 合并4张图片
        /// </summary>
        /// <param name="image1"></param>
        /// <param name="image2"></param>
        /// <param name="image3"></param>
        /// <param name="image4"></param>
        /// <param name="layout"></param>
        /// <returns></returns>
        public static Image Merge4Images(Image image1, Image image2, Image image3, Image image4, Merge4LayoutEnum layout = Merge4LayoutEnum.Merge4S, int size = 250)
        {
            var width = size;
            var height = size;
            var pf = PixelFormat.Format32bppArgb;
            using (var bg = new Bitmap(width, height, pf))
            {
                using (var g = Graphics.FromImage(bg))
                {
                    g.FillRectangle((Brush)Brushes.White, 0, 0, width, height);//全幅背景为白色
                    switch (layout)
                    {
                        /// <summary>
                        /// 4张图片,上面一个长方形,下面2个正方形并排
                        ///  ———————————————————
                        /// |         |        |
                        /// |    S1   |   S2   |
                        /// |         |        |
                        ///  ———————————————————
                        /// |         |        |
                        /// |    S3   |   S4   |
                        /// |         |        |
                        ///  ———————————————————
                        /// </summary>
                        case Merge4LayoutEnum.Merge4S:
                            {
                                using (var img1 = ZoomToSqure(image1, size))
                                {
                                    var newHeight = height / 2;//  =125
                                    var newWidth = width / 2;  //  =125
                                    var srcWidth = img1.Width; //  =250
                                    var srcHeight = img1.Height;// =250
                                    g.DrawImage(img1, new Rectangle(0, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img2 = ZoomToSqure(image2, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img2.Width; //   =250
                                    var srcHeight = img2.Height;//  =250
                                    g.DrawImage(img2, new Rectangle(width / 2, 0, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img3 = ZoomToSqure(image3, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img3.Width; //   =250
                                    var srcHeight = img3.Height;//  =250
                                    g.DrawImage(img3, new Rectangle(0, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                                using (var img4 = ZoomToSqure(image4, size))
                                {
                                    var newHeight = height / 2; //  =125
                                    var newWidth = width / 2;   //  =125
                                    var srcWidth = img4.Width; //   =250
                                    var srcHeight = img4.Height;//  =250
                                    g.DrawImage(img4, new Rectangle(width / 2, height / 2, newWidth, newHeight), new Rectangle(0, 0, srcWidth, srcHeight), GraphicsUnit.Pixel);
                                }
                            }
                            break;
                    }
                    g.Save();
                    image1.Dispose();
                    image2.Dispose();
                    image3.Dispose();
                    image4.Dispose();
                }
                using (var ms = new MemoryStream())
                {
                    bg.Save(ms, ImageFormat.Png);
                    var buffers = ms.ToArray();
                    return ConvertToImage(buffers);
                }
            }
        }
View Code

 

以下是用到的Helper方法:

        /// <summary>
        /// 下载图片
        /// </summary>
        /// <param name="imageUrl"></param>
        /// <returns></returns>
        public static byte[] Download(string imageUrl)
        {
            if (imageUrl.StartsWith("http"))
            {
                using (var ms = new MemoryStream())
                {
                    var request = (HttpWebRequest)HttpWebRequest.Create(imageUrl);// 打开网络连接
                    using (var rs = request.GetResponse().GetResponseStream())// 向服务器请求,获得服务器的回应数据流
                    {
                        byte[] btArray = new byte[512];// 定义一个字节数据,用来向readStream读取内容和向writeStream写入内容
                        int size = rs.Read(btArray, 0, btArray.Length);// 向远程文件读第一次

                        while (size > 0)// 如果读取长度大于零则继续读
                        {
                            ms.Write(btArray, 0, size);// 写入本地文件
                            size = rs.Read(btArray, 0, btArray.Length);// 继续向远程文件读取
                        }
                        return ms.ToArray();
                    }
                }
            }
            else
            {
                using (var ms = new MemoryStream())
                {
                    var img = Image.FromFile(imageUrl);
                    img.Save(ms, img.RawFormat);
                    return ms.ToArray();
                }
            }
        }

        /// <summary>
        /// 将byte数组转化为Image
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns></returns>
        public static Image ConvertToImage(byte[] buffer)
        {
            using (MemoryStream ms = new MemoryStream(buffer))
            {
                return Image.FromStream(ms);
            }
        }

        /// <summary>
        /// 将Image转化为byte数组
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        public static byte[] ConvertToByte(Image image)
        {
            using (MemoryStream ms = new MemoryStream())
            {
                image.Save(ms, image.RawFormat);
                return ms.ToArray();
            }
        }


        /// <summary>
        /// 等比缩放/放大成正方形图片
        /// </summary>
        /// <param name="orginal">原始图片</param>
        /// <param name="size">目标宽高</param>
        /// <param name="cute">超出部分是否剪裁</param>
        /// <returns></returns>
        public static Image ZoomToSqure(Image orginal, int size, bool cute = true)
        {
            var width = 0d;//图片宽度
            var height = 0d;//图片高度
            if (orginal.Width > orginal.Height)//原始图片宽度大于高度
            {
                height = size;
                width = cute ? size : (orginal.Width * height / orginal.Height);
            }
            else if (orginal.Width < orginal.Height)//原始图片高度大于宽度
            {
                width = size;
                height = cute ? size : (orginal.Height * width / orginal.Width);
            }
            else//原始图片是正方形,刚好
            {
                width = size;
                height = size;
            }
            var board = new Bitmap((int)width, (int)height);
            using (var g = Graphics.FromImage(board))
            {
                g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;//设置质量
                g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;//设置质量
                g.Clear(Color.White);//置背景色
                g.DrawImage(orginal, new Rectangle(0, 0, board.Width, board.Height), new Rectangle(0, 0, orginal.Width, orginal.Height), System.Drawing.GraphicsUnit.Pixel);  //画图
                orginal.Dispose();//释放原图
                return board;
            }
        }
View Code

 

完整代码点击:https://github.com/night-king/ImageMerge

         

posted @ 2019-06-20 12:22 夜の魔王 阅读(979) 评论(0) 推荐(1) 编辑
摘要: 本文探讨了两种比较简单的随机算法:无限次随机算法与固定奖项随机算法,并用C#分别实现了这两种算法,给出了算法1和算法2的测试结果。结果表明:随着抽奖次数的增加,算法1的抽奖结果越来越接近设定的中奖概率分布;算法2与设定一致。 阅读全文
posted @ 2016-12-27 14:15 夜の魔王 阅读(7463) 评论(0) 推荐(3) 编辑
摘要: 为了防止自己的劳动成果被别人窃取,混淆代码能有效防止被反编译 阅读全文
posted @ 2016-04-28 10:31 夜の魔王 阅读(538) 评论(0) 推荐(0) 编辑
摘要: 滴滴和快的烧钱的时代已经过去,在那个时代我们消费者着实得到了不少实惠。自从他们温柔的在一起之后,这种实惠就木有了。让我不禁感叹免费坐车的几率有降低了50%。前段时间,Uber悄无声息的进入我的视野,在朋友的引导下,我顺利体验了一把不一样的Uber打车服务,不禁为滴滴和快的捏了一把汗。 阅读全文
posted @ 2015-04-24 15:52 夜の魔王 阅读(1141) 评论(2) 推荐(1) 编辑
摘要: 目前微信公众平台正如火如荼的进行中,微信虽然在海外市场不敌WhatsApp,但是已经俘获了国内绝大部分用户的心。作为国内最大的,超级"app",微信已算是成功问鼎了。公众帐号百花齐放,各自SDK层出不穷,但是单单.net平台/C#的SDK也就那么几个值得一提:Senparc.Weixin.MP(以下简称Senparc) 和WeixinSDK.net(以下简称WeixinSDK)。ps:为什么官方没有完整的.net/C#版本?谁知道可以告诉我下。 阅读全文
posted @ 2015-04-21 16:35 夜の魔王 阅读(7299) 评论(1) 推荐(1) 编辑
摘要: 微信消息体签名及加密功能已上线,明文传输确实存在安全风险,鉴于微信的用户范围使用之广泛,必定会成为众矢之的。所以大家还是尽快接入安全模式为好。仔细阅读官方接入指南,发现这次安全升级只是涉及到用户在微信对话窗口中与公众好消息交互,所以此次升级还是比较简单的。下面为大家一一道来。 阅读全文
posted @ 2015-01-30 10:45 夜の魔王 阅读(4457) 评论(3) 推荐(1) 编辑
摘要: 今日,腾讯在推出windows桌面版的微信后,又发布了一个重量级产品:QQ浏览器微信版。我们在PC端用微信又多了一种方式,而且比windows桌面版本更加友好,更加方便。我相信:对于我们绝大多数办公室白领来说,浏览器是接触最多的软件了。下班后微信有是大多数人用的最多的app。这句话不同意的请留言反驳我。而QQ浏览器微信版正好把这两种需求完美的结合在一起。我看好微信,看好腾讯。腾讯不愧是中国最有价值的互联网公司(前几天在博客园新闻频道有报道过)。 阅读全文
posted @ 2015-01-29 16:40 夜の魔王 阅读(1008) 评论(6) 推荐(0) 编辑
摘要: 微信此次开放JS接口,开放了一大批api权限,即使在未认证的订阅号也可以使用图像接口,音频接口,智能接口,地理位置,界面操作,微信扫一扫等功能。要知道:以前订阅号只能接受和被动回复用户消息而已。微信官方没有给出.net版本,有java,node,php和python,唯独没有.net版本,这是怎么了?本文就教你实现.net版本的微信JS-SDK权限签名生成算法。 阅读全文
posted @ 2015-01-28 11:43 夜の魔王 阅读(23268) 评论(15) 推荐(6) 编辑
摘要: Douglas Peucker算法的C#实现 阅读全文
posted @ 2014-12-02 11:28 夜の魔王 阅读(2951) 评论(0) 推荐(2) 编辑
摘要: 一、为什么要生成说明文档我们大家都知道,自己写的API要供他人调用,就需要用文字的方式将调用方法和注意事项等写成一个文档以更好的展示我们设计时的想法和思路,便于调用者更加高效的使用我们的API。当然,您可以不借助任何工具,自己手工写文档,然后做成chm或者html的形式交给客户,就是效率有点低,并且... 阅读全文
posted @ 2014-08-22 15:36 夜の魔王 阅读(1669) 评论(1) 推荐(4) 编辑
点击右上角即可分享
微信分享提示