专注于前端开发, 追求更好的用户体验, 更好的开发体验 [长沙前端QQ群:234746733]

html5 canvas 前端生成缩略图

更新
2015/03/02: 解决了Chrome/IE11下面的图片空白问题;

  • 优先用二进制代替base64, 提升性能;
  • before/always 参数, 针对很大的图(>=20M), 缩图时间较长时, 可以设置loading提示. 2013/08/01: 解决了后面遇到> 的bug: 图片被压扁(IOS6); 图片被旋转;
    整个源码放在: https://github.com/kairyou/html5-make-thumb

新方案需要后面实现的, 就是下面的旧版本里的功能(水印/是否强制拉伸以适应目标尺寸等功能).

w3ctech长沙站交流会, 里面分享的PPT: http://www.slideshare.net/99leon/html5-create-thumbnail

之前有bug的版本放在分支old里(不推荐使用), 请使用更新的方案~

2013/01/07:
11年做的公司的移动页面, 上传图片时缩略图是靠后端生成, 但是随着现在的手机越来越牛X(摄像头比数码相机还厉害~), 图片体积也越来越大.
一个几M的图, 也许我们只是用来生成一个100*100的小图, 上传到后端再生成缩略图就大大的浪费了, 而且提交表单的等待时间也非长久, 对用户体验也不好.
普通的web表单, 上传图片靠后端来生成缩略图很平常, 但有了HTML5, 针对移动Web开发可以考虑使用前端生成缩略图了.

写了个生成缩略图的jquery的插件, 主要参数:

width: 生成缩略图的宽; height: 生成缩略图的高;
fill: 图片小于缩略图尺寸时, 是否填充(false: 缩略图宽高自动缩放到适应图片, true: 缩略图尺寸不变)
background:生成图片填充背景(默认#fff, 设置null时, 背景透明)
type: 生成图片类型 ('image/jpeg' 或 'image/png')
size: 生成缩略图方式, 生成缩略图的效果主要参考了CSS3的background-size属性:
  contain: 等比缩放并拉伸, 图片全部显示;
  cover: 等比缩放并拉伸, 图片把容器完全覆盖;
  auto: 图片不拉伸, 居中显示.
mark: 水印
  文字水印: mark = {padding: 5, height: 18, text: 'test', color: '#000', font: '400 18px Arial'}
  图片水印: mark = {padding: 5, src: 'mark.png', width: 34, height: 45};
stretch: 小图是否强制拉伸以适应缩略图的尺寸(size = auto/contain时)
success: 生成缩略图后 callback

大体思路如下:
首先判断是否支持fileReader(支持fileReader, canvas就不在话下了)
不支持的话: 不做任何操作, 默认的input type="file"上传, 靠后端生成缩略图.
支持的情况: input change时, 判断选择的文件是图片, 就创建一个隐藏的canvas, 并把图片画到canvas里,
因为要生成缩略图, 所以在canvas里画图的时候, 控制剪切坐标和被剪切的宽高就OK了.
另外可以加上水印, 图片水印或者文字水印加到canvas上面也是比较方便的.
最后 canvas.toDataURL 转成base64, post到后端(先把input type="file"移除, 再生成个新的input type="hidden"储存图片数据), 后端接收后直接保存为图片就OK了.
主要用到: FileReader和canvas, 一个用来读取本地图片, 一个用来生成缩略图.

做移动网页开发的同学可以考虑下.

/ 分类: 开发,实践 / TrackBackhttps://xhl.me/archives/create-thumbnail-images-html5/trackback标签: mobile web

已有 41 条评论 »

  1. onedot onedot

    LZ的帖子我用手机测试了下,有2个问题

    1.如果用IPHONE,调取相册里图片没有问题,但直接拍照就会出异常,图片截取的不完整

    2.如果使用安卓的机器,好像点击选取图片,图片选取确认后就没反应了。

    1. kairyou kairyou

      嗯, 是的. 你说的bug我们后面都测试到了, 这个我正准备从新整理一份解决后面出现bug的版本.

      1. onedot onedot

        呵呵,大概什么时候发啊,是8点20么

        1. kairyou kairyou

          哈~月底前肯定能整理出来, 正在写手机上传生成缩略图这方面的文档会在交流会上面分享.

      2. www1463 www1463

        android 2.3.7 don't support 有什么好的解决方法吗》急求

        1. kairyou kairyou

          Hi 你是说不支持前端生成吧, 不支持前端就用后端去处理咯.

          1. www1463 www1463

            我也想后端啊 可是在什么位置判断不支持然后转如后端呢?
            您的代码我一点点看 有的确实看不明白 请指教?

          2. kairyou kairyou

            www.dwz.cn/oIKwy 高亮行就是, 代码里已经判断了, 不支持会直接return掉. 然后就走普通的上传按钮流程了, 这时和插件就没有关系了.

          3. www1463 www1463

            多谢,我实验下!

  2. onedot onedot

    赞一个

    1. kairyou kairyou

      谢谢支持! 这个方案目前使用的人应该很少, 当初为了解决图片旋转和iOS6的问题, 的确花了不少精力, 国外也很少人讨论这个. 以后有其他想法和问题欢迎多交流~

    2. onedot onedot

      我们刚好也在HTML 5的WEB APP,也是考虑原生图片太大,3G情况下很慢

      1. kairyou kairyou

        赞下你们团队~

  3. name name

    挺不错的,

  4. khpop khpop

    请问怎么没有水印呢

    1. kairyou kairyou

      @khpop
      抱歉, 新版為了修復bug, 把這個移除了, 後面我再把水印相關的加上.

  5. paloalto paloalto

    建议加上手动裁剪。

  6. hzplay hzplay

    啊哦... 当我解决完了所有的问题之后发现原来不止我在做这个..

    1. kairyou kairyou

      @hzplay
      :) 握手!

  7. 古月摇光 古月摇光

    年初的时候也考虑过使用这个方法 后来发现phonegap里调用图片的时候本身就可以设置缩放比例 所以就没有继续研究了,不过最近项目中要把网络下载到的图片生成缩略图并保存,似乎使用前端会更高效且简单。

添加新评论 »