关键点:

  • jquery.ajax 方法 和 HTML5 中的 FileReader对象
  • ashx 处理程序
  • asp.net  的 ScriptManager.RegisterStartupScript 调用客户端js脚本

一、ASP.NET 前台源码:

  1. <%@ Page Language="C#" AutoEventWireup="true" CodeFile="load_pic.aspx.cs" Inherits="Default2" %>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml">
  4. <head runat="server">
  5. <title></title>
  6. <script type="text/javascript" src="Scripts/jquery-1.4.1.min.js"></script>
  7. <script type="text/javascript" src="Scripts/jquery-extend.js"></script>
  8. </head>
  9. <body>
  10. <form id="form1" runat="server">
  11. <div>
  12. <!-- 把浏览图片解析为 base64 字符串 ,通过 jQuery.ajax + ashx 异步保存到数据库中 -->
  13. <input type='file' onchange="readURL(this);" />
  14. <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="C#后台读取显示" />
  15. <!-- 存储 base64 字符串 ,方便在后台处理 -->
  16. <asp:HiddenField ID="hf_base64" runat="server" />
  17. </div>
  18. <div>
  19. <img id="img_prev" src="#" alt="your image" /></div>
  20. </form>
  21. </body>
  22. </html>

二、jquery-extent.js 代码

  1. /* 客户端按比例预览、上传图片 要求:jquery-1.4.1.min.js */
  2. //================================================================================================
  3. function readURL(input) {
  4. if (input.files && input.files[0]) {
  5. var reader = new FileReader();
  6. var maxWidth = 200, maxHeight = 200;
  7. reader.onload = function (e) {
  8. var base64 = e.target.result;
  9. loadbase64(base64, maxWidth, maxHeight);
  10. $("#hf_base64").val(base64);
  11. };
  12. reader.readAsDataURL(input.files[0]);
  13. }
  14. }
  15. // imgobj : img 标签对象,根据容器自动调整宽、高
  16. function load_obj_base64(imgobj, base64) {
  17. maxWidth = $(imgobj).width();
  18. maxHeight = $(imgobj).height();
  19. $("<img/>") // 在内存中创建一个img标记
  20. .attr("src", base64)
  21. .load(function () {
  22. var w, h;
  23. w = this.width;
  24. h = this.height;
  25. if (w < maxWidth && h < maxHeight) { }
  26. else
  27. { w / h > maxWidth / maxHeight ? this.width = maxWidth : this.height = maxHeight; }
  28. $(imgobj).replaceWith(this);
  29. });
  30. }
  31. function loadbase64(base64, maxWidth, maxHeight) {
  32. $("<img/>") // 在内存中创建一个img标记
  33. .attr("src", base64).attr("id", "img_prev")
  34. .load(function () {
  35. var w, h;
  36. w = this.width;
  37. h = this.height;
  38. // 当图片比预览区域小时不做任何改变
  39. if (w < maxWidth && h < maxHeight) { }
  40. else
  41. // 当实际图片比例大于预览区域宽高比例时
  42. // 缩放图片宽度,反之缩放图片宽度
  43. { w / h > maxWidth / maxHeight ? this.width = maxWidth : this.height = maxHeight; }
  44. $('#img_prev').replaceWith(this);
  45. $.ajax({
  46. async: false,
  47. type: 'POST',
  48. url: "uploadhandler.ashx",
  49. data: {
  50. file: base64
  51. },
  52. success: function (data) {
  53. //$j('#img_wait').css('display', 'none');
  54. },
  55. beforeSend: function (xhr) {
  56. //$j('#img_wait').css('display', 'inline');
  57. }
  58. });
  59. });
  60. }

三、uploadhandler.ashx

  1. <%@ WebHandler Language="C#" Class="uploadhandler" %>
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.IO;
  6. using System.Net;
  7. using System.Web;
  8. using System.Web.Services;
  9. [WebService(Namespace = "http://tempuri.org/")]
  10. [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
  11. public class uploadhandler : IHttpHandler
  12. {
  13. public void ProcessRequest(HttpContext context)
  14. {
  15. context.Response.ContentType = "text/plain";
  16. context.Response.Charset = "utf-8";
  17. try
  18. {
  19. HttpPostedFile file = context.Request.Files["Filedata"];
  20. DBUtility.IDBHelper dbhelper = new DBUtility.SqlHelper();
  21. string strSql = "UPDATE [LDZ] set Photo = @imagedata WHERE [ID] = 13;";
  22. byte[] buffer = null;
  23. if (file != null)
  24. {
  25. buffer = getByte(file);
  26. }
  27. else
  28. {
  29. string img = context.Request.Params["file"];
  30. img = img.Substring(img.IndexOf("base64,") + 7);
  31. buffer = Convert.FromBase64String(img);
  32. }
  33. int r = dbhelper.ExecuteNonQuery(WebConfig.DB_CONN, System.Data.CommandType.Text,
  34. strSql,new System.Data.SqlClient.SqlParameter("@imagedata", buffer));
  35. context.Response.Write("1");
  36. }
  37. catch (Exception ex)
  38. {
  39. context.Response.Write("0");
  40. }
  41. }
  42. private byte[] getByte(HttpPostedFile file)
  43. {
  44. byte[] buffer = new byte[file.ContentLength];
  45. file.InputStream.Read(buffer, 0, buffer.Length);
  46. return buffer;
  47. }
  48. public bool IsReusable
  49. {
  50. get
  51. {
  52. return false;
  53. }
  54. }
  55. //图片转为base64编码的字符串
  56. protected string ImgToBase64String(string Imagefilename)
  57. {
  58. try
  59. {
  60. System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);
  61. MemoryStream ms = new MemoryStream();
  62. bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
  63. byte[] arr = new byte[ms.Length];
  64. ms.Position = 0;
  65. ms.Read(arr, 0, (int)ms.Length);
  66. ms.Close();
  67. return Convert.ToBase64String(arr);
  68. }
  69. catch (Exception ex)
  70. {
  71. return null;
  72. }
  73. }
  74. //base64编码的字符串转为图片
  75. protected System.Drawing.Bitmap Base64StringToImage(string strbase64)
  76. {
  77. try
  78. {
  79. byte[] arr = Convert.FromBase64String(strbase64);
  80. MemoryStream ms = new MemoryStream(arr);
  81. System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(ms);
  82. //bmp.Save("test.jpg", System.Drawing.Imaging.ImageFormat.Jpeg);
  83. ms.Close();
  84. return bmp;
  85. }
  86. catch (Exception ex)
  87. {
  88. return null;
  89. }
  90. }
  91. }

四、ASP.NET 后台代码

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.UI;
  6. using System.Web.UI.WebControls;
  7. using System.Data;
  8. public partial class Default2 : System.Web.UI.Page
  9. {
  10. protected void Page_Load(object sender, EventArgs e)
  11. {
  12. }
  13. protected void Button1_Click(object sender, EventArgs e)
  14. {
  15. DBUtility.IDBHelper dbhelper = new DBUtility.SqlHelper();
  16. string strSql = "select Photo from [LDZ] WHERE [ID] = 13;";
  17. DataSet r = dbhelper.ExecuteQuery(WebConfig.DB_CONN, System.Data.CommandType.Text, strSql);
  18. object imgObj = r.Tables[0].Rows[0]["Photo"];
  19. string base64 = "data:image/jpeg;base64,";
  20. if (imgObj != System.DBNull.Value)
  21. {
  22. byte[] buffer = (byte[])imgObj;
  23. base64 += Convert.ToBase64String(buffer);
  24. }
  25. string hf_base64 = this.hf_base64.Value;
  26. ScriptManager.RegisterStartupScript(this, this.GetType(), "",
  27. "loadbase64('" + base64 + "', 500, 500)", true);
  28. }
  29. }

注:ajax 方式异步读取数据库显示图片的方法同上传一致,使用 ashx 返回base64字符串在客户端处理即可。

记录一个让我纠结良久的问题:

在Page_Load 函数中,只有第一个用 ScriptManager.RegisterStartupScript 注册的脚本才有效

  1. /// <summary>
  2. /// 此函数范围内只有第一个用 ScriptManager.RegisterStartupScript 注册的脚本才有效
  3. /// </summary>
  4. protected void Page_Load(object sender, EventArgs e)
  5. {
  6. if (!IsPostBack)
  7. {
  8. // 首次加载的处理方法
  9. if (this.Request.Params["lid"] != null)
  10. {
  11. // 照片处理,从数据获取过程省略......
  12. object imgObj = row["Photo"];
  13. string base64 = "data:image/jpeg;base64,";
  14. if (imgObj != System.DBNull.Value)
  15. {
  16. byte[] buffer = (byte[])imgObj;
  17. base64 += Convert.ToBase64String(buffer);
  18. this.hf_base64.Value = base64;
  19. // js脚本 load_obj_base64 是用来在客户端渲染图片的
  20. string script = "$('#lz_caption strong').text('修改楼长信息');"
  21. +"load_obj_base64($('#photo_lz').parent().next().children('img'),'"+ base64 + "')";
  22. ScriptManager.RegisterStartupScript(this, this.GetType(), "",script, true);
  23. }
  24. }
此示例的前提是浏览器必须支持 HTML5 ,但现在的IE对 HTML5支持太烂,如需在 IE中使用,请参考下一篇:IE 中上传前按比例预览图片

jQuery + ashx 实现图片按比例预览、异步上传及显示的更多相关文章

  1. 基于“formData批量上传的多种实现” 的多图片预览、上传的多种实现

    前言 图片上传是web项目常见的需求,我基于之前的博客的代码(请戳:formData批量上传的多种实现)里的第三种方法实现多图片的预览.上传,并且支持三种方式添加图片到上传列表:选择图片.复制粘贴图片 ...

  2. 原生js实现图片预览并上传

    最近主导的PC客户端网站重构工程告一段落,下一阶段开始给公司APP开发H5页面,技术栈是react.最近碰到一个需求:需要在H5页面上添加身份证照片,预览并上传.因为要兼容安卓4.4以下版本的手机,所 ...

  3. 用js实现预览待上传的本地图片

    js实现预览待上传的本地图片,代码如下: <form name="form5" id="form5" method="post" ac ...

  4. 网站中集成jquery.imgareaselect实现图片的本地预览和选择截取

    imgAreaSelect 是由 Michal Wojciechowski开发的一款非常好用的jquery插件,实现了图片的截取功能.其文档和Demo也是很详尽的.大家可以到http://odynie ...

  5. jquery+html5+canvas实现图片 预览 压缩 上传

    javascirpt (function($){ $.fn.extend({ aiiUpload:function(obj) { if(typeof obj !="object") ...

  6. H5-FileReader实现图片预览&Ajax上传文件

    图片预览 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF- ...

  7. 前端图片预览,上传前预览,兼容IE7、8、9、10、11,Firefox,Chrome(学习到的知识)

    文章地址:http://www.cnblogs.com/rubylouvre/p/4597344.html 一.window.URL 在Chrome中,window.URL和window.webkit ...

  8. 如何预览将要上传的图片-使用H5的FileAPI

    这篇将要说的东西已经不新鲜了. 参考资料: Reading files in JavaScript using the File APIs (鉴于作者在美国, 我姑且认为作者母语是英语, 当然链接中有 ...

  9. vue组件利用formdata图片预览以及上传《转载》

    转载修改 在项目中直接新建一个单文件页,复制一下代码即可       upload组件: <template> <div class="vue-uploader" ...

随机推荐

  1. keepalived双主虚拟路由配置

    我使用了两台虚拟机做测试 系统centos7.3 主机A:172.16.1.123 主机B:172.16.1.124 其实和普通配置keepalived差不多,就是复制多了一个vrrp_instanc ...

  2. 2019暑假牛客多校训练-第八场-C-CDMA(递归、水题)

    观察前3组可以推出递归规律,生成下一个类型时,每行copy自身与自身相反. 题目描述 Gromah and LZR have entered the third level. There is a b ...

  3. redis使用bit做只有两种情况的“状态“统计(如是否在线的用户统计)

    1 记录在线用户数(活跃用户)? 比如redis中键a的value数据的二进制码是 0110 0110 0001 它总共有12位,在redis的位操作中,二进制中的第几位称为offset. 我们可以这 ...

  4. Java开发笔记(一百二十五)AWT图像加工

    前面介绍了如何使用画笔工具Graphics绘制各种图案,然而Graphics并不完美,它的遗憾之处包括但不限于:1.不能设置背景颜色:2.虽然提供了平移功能,却未提供旋转功能与缩放功能:3.只能在控件 ...

  5. Python规范:用用assert

    什么是assert assert的语法: assert_stmt ::= "assert" expression ["," expression] 例: ass ...

  6. 我在LeetCode的首次刷题

    到现在为止,我才发现我的博客一篇感受,心得,体会之言都没有. 今天就来随便扯扯. 刷题,是我最近一直在干的事情.也就每天写一两个.忘了就没写这种.也收藏了好几个刷题网站,当然第一次接触肯定是 WUST ...

  7. C++ 多态详解及常见面试题

    今天,讲一讲多态: 多态就是不同对象对同一行为会有不同的状态.(举例 : 学生和成人都去买票时,学生会打折,成人不会) 实现多态有两个条件: 一是虚函数重写,重写就是用来设置不同状态的   二是对象调 ...

  8. xorm -Get方法实例

    查询单条数据使用Get方法,在调用Get方法时需要传入一个对应结构体的指针,同时结构体中的非空field自动成为查询的条件和前面的方法条件组合在一起查询 package main import ( & ...

  9. Linux 下随机启动自己的应用 -请使用while(true) 不要Console.ReadKey()

    Linux 下随机启动 自己的应用 -请使用while(true) 不要Console.ReadKey() 开机启动脚本启动,某些程序无法启动 原因 例如写了一个服务,不能停止程序运行,所以主线程成不 ...

  10. int and Integer

    int和Integer的区别 1.Integer是int的包装类,int则是java的一种基本数据类型 2.Integer变量必须实例化后才能使用,而int变量不需要 3.Integer实际是对象的引 ...