动态生成图片(验证码,缩略图,水印图等)
要想在页面上看到图片有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"); }
浙公网安备 33010602011771号