zoukankan      html  css  js  c++  java
  • 移动端使用localResizeIMG4压缩图片

    移动h5开发避免不了上传图片,一般我们使用html自带的控件input或者使用微信上传API。但微信上传API不是任何地方都可以使用的,使用html自带的控件input上传又免不了图片体积太大,上传不稳定。localResizeIMG4就是为此而生的。

    本文演示版本localResizeIMG 4.9.35。

    特点

    兼容IOS,Android,PC、自动按需加载文件
    支持压缩比例
    支持原生JS、jQuery/Zepto
    支持Promise特性
    使用Base64

    下载地址

    localResizeIMG共有4个历史版本,每个版本间使用方法可能不一样。本文以最新稳定版本localResizeIMG4为例。

    https://github.com/think2011/localResizeIMG/archive/4.9.35.zip

    如何使用

    页面引入

    <script src="./dist/lrz.bundle.js"></script>
    

    html

    <input type="file" capture="camera" accept="image/*" name="logo" id="file">
    

    capture="camera"可以出现拍照;
    accept="image/*"仅接受图片

    通过change事件可以得到用户选择的图片。

    使用原生js

    document.querySelector('input').addEventListener('change', function () {
        // this.files[0] 是用户选择的文件
        lrz(this.files[0], { 1024})
            .then(function (rst) {
            
                // 把处理的好的图片给用户看看呗(可选)
                var img = new Image();
                img.src = rst.base64; //base64字符串
    
                img.onload = function () {
                    document.body.appendChild(img);
                };
    
                return rst;
            })
    
            .then(function (rst) {
                // 这里该上传给后端啦
    
                /* ==================================================== */
                // 原生ajax上传代码,所以看起来特别多,但绝对能用
                // 其他框架,例如jQuery处理formData略有不同,请自行google,baidu。
                var xhr = new XMLHttpRequest();
                xhr.open('POST', 'http://localhost:5000/');
    
                xhr.onload = function () {
                    if (xhr.status === 200) {
                        // 上传成功
                    } else {
                        // 处理其他情况
                    }
                };
    
                xhr.onerror = function () {
                    // 处理错误
                };
    
                xhr.upload.onprogress = function (e) {
                    // 上传进度
                    var percentComplete = ((e.loaded / e.total) || 0) * 100;
                };
    
                // 添加参数
                rst.formData.append('fileLen', rst.fileLen);
                rst.formData.append('xxx', '我是其他参数');
    
                // 触发上传
                xhr.send(rst.formData);
                /* ==================================================== */
    
                return rst;
            })
    
            .catch(function (err) {
                // 万一出错了,这里可以捕捉到错误信息
                // 而且以上的then都不会执行
    
                alert(err);
            })
    
            .always(function () {
                // 不管是成功失败,这里都会执行
            });
    });
    

    返回的rst对象数据示例:

    {origin: File, base64: "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD…iigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/Z", base64Len: 1507}
    
    origin: File
    lastModified: 1442482311173
    lastModifiedDate: Thu Sep 17 2015 17:31:51 GMT+0800 (中国标准时间)
    name: "upload-add.png"
    size: 291
    type: "image/png"
    webkitRelativePath: ""
    

    其中base64属性是带图片类型的base64编码,可直接用于img标签的src。如果后端需要将这个属性值转为图片保存,就要先去除图片类型,文章后面有示例。之前的版本localResizeIMG1会同时返回result.base64result.clearBase64(不带图片类型的编码)。

    使用jQuery/Zepto

    $(function(){
    	$('input[name=logo]').on('change', function(){
    		 lrz(this.files[0], { 640})
    	        .then(function (rst) {
    
    	            $.ajax({
    	            	url: site_url + 'api/user/updLogo',
    	                type: 'post',
    	                data: {img: rst.base64},
    	                dataType: 'json',
    	                timeout: 200000,
    	                error: doAjax.error,
    	                success: doAjax.success,
    		        });
    	                
    	        })
    	        .catch(function (err) {
    
    	        })
    	        .always(function () {
    
    	        });
    	});
    });
    

    如果您的图片不是来自用户上传的,那么也可以直接传入图片路径:

    lrz('./xxx/xx/x.png')
            .then(function (rst) {
                // 处理成功会执行
            })
            .catch(function (err){
                // 处理失败会执行
            })
            .always(function () {
                // 不管是成功失败,都会执行
            });
    

    后端处理(PHP)

    $base64_image_content = $_POST['img'];
    
    if (preg_match('/^(data:s*image/(w+);base64,)/', $base64_image_content, $result)){
        $type = $result[2]; //jpeg
        
        //去除图片类型
        $img = base64_decode(str_replace($result[1], '', $base64_image_content)); //返回文件流
    }
    
    //使用AliOSS上传
    $url = OSS::upload($img, $type);
    

    其中$result内容:

    Array
    (
        [0] => data:image/jpeg;base64,
        [1] => data:image/jpeg;base64,
        [2] => jpeg
    )
    

    完整例子(HTML+PHP)

    请在服务器环境(如LAMP)运行。

    index.html

    <!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <title>移动端使用localResizeIMG4压缩图片</title>
    	<script src="./dist/lrz.bundle.js"></script>
    	<script src="./dist/zepto.min.js"></script>
    </head>
    
    <body>
        上传图片<input type="file" capture="camera" accept="image/*" name="logo" id="file">
    	<script>
    	$(function(){
    		$('input[name=logo]').on('change', function(){
    			 lrz(this.files[0], { 640})
    				.then(function (rst) {
    				
    					console.log(rst);
    
    					$.ajax({
    						url: 'upload.php',
    						type: 'post',
    						data: {img: rst.base64},
    						dataType: 'json',
    						timeout: 200000,
    						success: function (response) {
    							if (response.ecd == '0') {
    								alert('成功');
    								return true;
    							} else {
    								return alert(response.msg);
    							}
    						},
    
    						error: function (jqXHR, textStatus, errorThrown) {
    							
    							if (textStatus == 'timeout') {
    								a_info_alert('请求超时');
    
    								return false;
    							}
    
    							alert(jqXHR.responseText);
    						}
    					});
    						
    				})
    				.catch(function (err) {
    
    				})
    				.always(function () {
    
    				});
    		});
    	});
    	</script>
    </body>
    

    upload.php

    <?php
    
    $base64_image_content = $_POST['img'];
    
    if (preg_match('/^(data:s*image/(w+);base64,)/', $base64_image_content, $result)){
        $type = $result[2]; //jpeg
        $img = base64_decode(str_replace($result[1], '', $base64_image_content)); //返回文件流
    }
    
    //var_dump($_POST); //string(1507) "data:image/jpeg;base64,/9j/4AAQSkZJR...
    //var_dump($result); //"data:image/jpeg;base64,"  "data:image/jpeg;base64,"   "jpeg"
    //var_dump($img); //返回的是资源,直接使用<img src="$img" />可以显示图片
    
    /* 输出到文件 */
    //方式一:直接使用file_put_contents
    $tmp_file = time(). '.' .$type;
    //file_put_contents($tmp_file, $img); //可以直接将文件流保存为本地图片
    
    //方式二:先转换为GD图像资源,再生成文件或显示输出
    $im = imagecreatefromstring($img); //resource(2) of type (gd) 图像资源
    imagejpeg ($im, $tmp_file); //图像流(image)以 JPEG 格式输出到标准输出(浏览器或者文件)
    
    //或者使用AliOSS上传
    //$url = OSS::upload($img, $type);
    
    return ajaxReturn($tmp_file);
    
    function ajaxReturn($data = array(), $code = 0, $msg = '成功'){
    	$result =  array(
    		'result' => $data,
    		'ecd' => $code,
    		'msg' => $msg,
    	);
    	
    	echo json_encode($result);
    	exit;
    }
    
    

    示例代码在github上:https://github.com/52fhy/localResizeIMG4/tree/master/lrz

    参数文档

    参数

    lrz(file, [options]);
    
    • file 通过 input:file 得到的文件,或者直接传入图片路径

    • [options] 这个参数允许忽略

      • width {Number} 图片最大不超过的宽度,默认为原图宽度,高度不设时会适应宽度。
      • height {Number} 同上
      • quality {Number} 图片压缩质量,取值 0 - 1,默认为0.7
      • fieldName {String} 后端接收的字段名,默认:file

    返回结果

    返回值是一个promise对象

    • then(rst)

      • rst.formData 后端可处理的数据
      • rst.file 压缩后的file对象(默认已经丢在rst.formData有一份了),需要注意的是如果压缩率太低的话,这个会是原始的file对象
      • rst.fileLen 生成后的图片的大小,后端可以通过此值来校验是否传输完整
      • rst.base64 生成后的图片base64,后端可以处理此字符串为图片,也直接用于img.src = base64
      • rst.base64Len 生成后的base64的大小,后端可以通过此值来校验是否传输完整 (如果采用base64上传方式)
      • rst.origin 也就是原始的file对象,里面存了一些原始文件的信息,例如大小,日期等。
    • catch(err)

    • always()

    lrz的历史

    • lrz1,基于jquery,使用需要引用jquery.js、localResizeIMG.js、patch/mobileBUGFix.mini.js(客户端)。
    • lrz2,基于原生js,却是用coffeescript写的 Orz, 有UI,存在已知BUG。
    • lrz3,基于原生js,提供pc & mobile版本,修复BUG和疑问,再一次重构了代码,移除了UI,仅作为纯粹的工具,方便二次开发。
    • lrz4,基于原生js,已升级到稳定版本,推荐使用。

    lrz原理

    基本原理是通过canvas渲染图片,再通过 toDataURL 方法压缩保存为base64字符串(能够编译为jpg格式的图片)。

    详见WIKI

    如何自定义上传按钮

    默认的上传按钮不好看,而且安卓和iPhone也不一样。需要进行统一:

    原理就是使用背景图,把input本身透明度设置为0.

    <div style="background:url(images/upload-add.png) no-repeat right/40px;"> 
        <input type="file" capture="camera" accept="image/*" name="logo" id="file" class="selectinput" style="100%;opacity:.01">
    </div>
    

    1、php读取和保存base64编码的图片内容 - fxhover的个人空间 - 开源中国社区
    http://my.oschina.net/fxhover/blog/209277
    2、参数文档 · think2011/localResizeIMG Wiki
    https://github.com/think2011/localResizeIMG/wiki
    3、think2011/localResizeIMG: 前端本地客户端压缩图片,兼容IOS,Android,PC、自动按需加载文件
    https://github.com/think2011/localResizeIMG

  • 相关阅读:
    js正则匹配
    包含HTML的字符串去掉HTML标签
    smart-table 服务端请求真分
    禁用H5 表单验证novalidate
    webpack
    linux 进程查看及杀死进程
    配置ca服务器和http,mail加密
    mysql权限
    mysql查询
    mysql储存引擎
  • 原文地址:https://www.cnblogs.com/52fhy/p/5355601.html
Copyright © 2011-2022 走看看