动态生成图片(验证码,缩略图,水印图等)

要想在页面上看到图片有2种方式,一种直接读取磁盘上的真是图片,另外一种就是通过程序动态的构造一张图片,然后将其写入http相应流里输出到客户端,同时也能保存到磁盘上。

1、动态的构造一张图片

 public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "image/jpeg";
            string name = context.Request["name"] ?? "";
            string ip=context.Request.UserHostAddress;

            using (Image img = new Bitmap(100,100))
            {
                //载入画布
                Graphics g = Graphics.FromImage(img);
                //清空画布原来背景色,并填充新的背景色
                g.Clear(Color.Brown);
                //在画布上画
                g.DrawString(name + Environment.NewLine + ip, new Font(FontFamily.GenericSerif, 15), Brushes.Black, 10, 20);
                //将图片保存到http影响输出流里
                img.Save(context.Response.OutputStream, ImageFormat.Jpeg);      
            }

        }

2、上传带水印的图片

 最终图片=水印图片+水印文字

 public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            if (context.Request.Files.Count > 0)
            {
                if (context.Request.Files[0].ContentLength > 0)
                {
                    HttpPostedFile hpf = context.Request.Files[0];
                    //不通过后缀的方式是为了防止有些人恶意的其他文件修改后缀名为image的格式的
                    //所以可以获取到上传文件的文件头(context.Request.Files[0].ContentType)来判断是不是image,而不是错误的获取本次的请求头
                    //无论传什么文件,请求头都是类似这种的 Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryF3BahnSYeYf7U8uU
                    if (hpf.ContentType.StartsWith("image"))
                    {

                        string fileName = Guid.NewGuid().ToString() + "_" + hpf.FileName;

                        //通过哈希码来自动生成目录,每一层可以生成16中文件夹,一共可以生成8层,故一共16^8次方个文件夹。
                        //object的GetHashCode()返回的是一个整数值,整数4个字节,一个字节8位,故一个整数由32个二进制0,1组成
                        //让该二进制和“1111”进行与操作,返回的就是一个整数,它的范围是(0,15)共16个情况
                        //将原二进制右移动4位,再和“1111”进行与操作,返回的也是一个整数,它的范围是(0,15)共16个情况
                        //以此类推,一个整数可以进行8次与操作,故有8级目录,每级16种情况,一共16^8次方个文件夹。
                        int hashcode = fileName.GetHashCode();
                        int dir1 = hashcode & 0xf;
                        int dir2 = (hashcode >> 4) & 0xf;

                        string path = Path.Combine(context.Request.MapPath("/upload/"), dir1.ToString(), dir2.ToString());
                       
                        if (!Directory.Exists(path))
                        {
                            Directory.CreateDirectory(path);
                        }
                        try
                        {
                            using (Image img = Image.FromStream(hpf.InputStream))
                            {
                                Graphics g = Graphics.FromImage(img);
                                using (Image imgSy = Image.FromFile(context.Request.MapPath("/images/sy.png")))
                                {
                                    //将水印图片华仔画布上
                                    g.DrawImage(imgSy, 0, 0);
                                }
                                //在画布上加上水印文字
                                g.DrawString("wuqiongle", new Font(FontFamily.GenericSansSerif, 14), Brushes.Red, 20, 130);
                                //将图片保存到磁盘文件里
                                img.Save(path + "/" + fileName);
                            }
                        }
                        catch (Exception ex)
                        {
                            context.Response.Write("失败了,重试吧" + ex.Message);
                        }
                    }
                    else
                    {
                        context.Response.Write("不是图片");
                    }

                }
            }


        }

 3、生成缩略图

public void ProcessRequest(HttpContext context)
        {
            context.Response.ContentType = "text/plain";
            if (context.Request.Files.Count > 0)
            {
                HttpPostedFile hpf = context.Request.Files[0];
                if (hpf.ContentLength > 0 && hpf.ContentType.StartsWith("image"))
                {
                    using (Image image = Image.FromStream(hpf.InputStream))
                    {
                        int oWidth = image.Width;
                        int oHeight = image.Height;

                        //缩略图:等比例缩小
                        int nWidth = 100;
                        //切记:千万不要写成 100 / oWidth * oHeight,不然会哭晕在厕所的。。。
                        int nHeight = 100 * oHeight / oWidth;
                        using (Image img = new Bitmap(nWidth, nHeight))
                        {
                            Graphics g = Graphics.FromImage(img);
                            //此函数的这个重载的用法一定要注意:在新画布上的起始点(0,0)的位置把原图像投影为指定大小(nWidth, nHeight)的图像,
                            //如果新画布过大,而投影的图片很小的话,则新画布上的只有大小为(nWidth, nHeight)的缩略图,其他为画布的默认部分
                            //如果新画布过小,而投影的图片很大的话,则新画布上会显示不全缩略图,
                            //总之,这个重载方法,不是截取图片,而是将图片变为缩略图而已,有时,缩略图大于画布的话才会造成所谓的“截图”的假象
                            g.DrawImage(image, 0, 0, nWidth, nHeight);

                            image.Save(context.Request.MapPath("/upload/original/" + hpf.FileName));
                            img.Save(context.Request.MapPath("/upload/thumbnail/" + hpf.FileName));
                        }
                    }
                }
            }
            context.Response.Write("OK");
        }

 

posted on 2017-05-09 12:17  奔游浪子  阅读(499)  评论(0)    收藏  举报

导航