上传图片时压缩图片 - 前端(canvas)做法
HTML前端代码:
<?php $this->layout('head'); ?> <?php $this->layout('sidebar'); ?> <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /> <style type="text/css"> #preview { display: inline-block; width: 24.56rem; height: 24.56rem; position: relative; background-image: url(img/iconfont-tianjia.png); background-repeat: no-repeat; background-size:cover ; } #file { /*width: 100%;*/ height: 100%; /*opacity: 0;*/ position: absolute; left: 0; top: 0; cursor: pointer; z-index: 5; } </style> <!-- Content Wrapper. Contains page content --> <div class="content-wrapper"> <!-- Content Header (Page header) --> <section class="content-header"> </section> <div class="col-md-12"> <div class="box"> <div class="box-header with-border"> <h3 class="box-title">商品图库</h3> </div> <!-- 第一种 --> <input type="file" accept="image/*" name="picture" id="file" value="点击" /> <div id="preview"></div> <!-- 第二种 --> <input type="file" id="tesImg" onchange="tes(this)" /> <img id="tesId"> <img id="tesId1"> <img id="tesId2"> <!-- /.box-header --> <div class="box-body" style="font-size: 1.3rem"> </div><!-- /.box-body --> <div class="box-footer clearfix "> </div> </div><!-- /.box --> </div> <div class=" clearfix "></div> </div> <?php $this->layout('footer'); ?> <!-- 第一种 --> <script type="text/javascript"> var eleFile = document.querySelector('#file'); var preview = document.querySelector('#preview'); // 压缩图片需要的一些元素和对象 var reader = new FileReader(), //创建一个img对象 img = new Image(); // 选择的文件对象 var file = null; // 缩放图片需要的canvas var canvas = document.createElement('canvas'); var context = canvas.getContext('2d'); // base64地址图片加载完毕后 img.onload = function() { // 图片原始尺寸 var originWidth = this.width; var originHeight = this.height; // 最大尺寸限制,可通过设置宽高来实现图片压缩程度 var maxWidth = 800, maxHeight = 800 // 目标尺寸 var targetWidth = originWidth, targetHeight = originHeight; // 图片尺寸超过400x400的限制 if(originWidth > maxWidth || originHeight > maxHeight) { if(originWidth / originHeight > maxWidth / maxHeight) { // 更宽,按照宽度限定尺寸 targetWidth = maxWidth; targetHeight = Math.round(maxWidth * (originHeight / originWidth)); } else { targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } } // canvas对图片进行缩放 canvas.width = targetWidth; canvas.height = targetHeight; // 清除画布 context.clearRect(0, 0, targetWidth, targetHeight); // 图片压缩 context.drawImage(img, 0, 0, targetWidth, targetHeight); /*第一个参数是创建的img对象;第二个参数是左上角坐标,后面两个是画布区域宽高*/ //压缩后的图片base64 url /*canvas.toDataURL(mimeType, qualityArgument),mimeType 默认值是'image/jpeg'; * qualityArgument表示导出的图片质量,只要导出为jpg和webp格式的时候此参数才有效果,默认值是0.92*/ var newUrl = canvas.toDataURL('image/jpeg', 0.8);//base64 格式 $.post( '/business/test_canvas' ,{img:newUrl} ,function(data){ console.log(data); } ); // console.log(canvas.toDataURL('image/jpeg', 0.92));return; preview.style.backgroundImage='url(' + newUrl + ')'; }; // 文件base64化,以便获知图片原始尺寸 reader.onload = function(e) { img.src = e.target.result; }; eleFile.addEventListener('change', function(event) { file = event.target.files[0]; // 选择的文件是图片 if(file.type.indexOf("image") == 0) { reader.readAsDataURL(file); } }); </script> <!-- 第二种 --> <script> /* var imgOb=new Image(); var imgDom=$("#tesId"); imgOb是图片对象,而imgDom是dom对象; imgDom[0]是图片对象,与imgOb一样。 要想获取图片对象的宽与高 必须等图片对象加载后才能获取 imgOb.onload=function(e){ alert(imgOb.width); alert(imgOb.width); } */ function tes(ob){ var file=ob.files[0]; var reader=new FileReader(); reader.readAsDataURL(file); reader.onload=function(e){ var imgObj=new Image(); imgObj.src=this.result; imgObj.onload=function(a){ var canvas = document.createElement('canvas'); canvas.width = 100; canvas.height = 100; var ctx = canvas.getContext("2d"); ctx.drawImage(imgObj, 0, 0, 100, 100); $("#tesId").attr('src',canvas.toDataURL("image/jpeg", 0.9)); canvas.width = 800; canvas.height = 800; ctx.drawImage(imgObj, 0, 0, 800, 800); var img = canvas.toDataURL("image/jpg", 0.1); $("#tesId1").attr('src',canvas.toDataURL("image/jpg", 0.1)); $.post( '/business/test_canvas' ,{img: img} ,function(data){ } ); canvas.width = 300; canvas.height = 100; ctx.drawImage(imgObj, 0, 0, 300, 100); $("#tesId2").attr('src',canvas.toDataURL("image/jpeg", 0.6)); } } } </script>
PHP后端接收前端 ajax方法传来base64格式图片保存:
// 测试canvas public function test_canvas() { if($_POST){ // echo new BasicReturn(true, 0, '', $_POST); $img = $_POST['img']; $abs_path = \sdk\config\Config::getUpPath()['upload']; $goods_path = "goods/" . date("Y/m/d/"); //图片上传路径 if (!file_exists($abs_path . $goods_path)) mkdir($abs_path . $goods_path, 0777, 1); $file_name = microtime(true) * 10000; $imgPath = $goods_path . $file_name; // 保存图片 $type = $this->save_img_real($abs_path . $imgPath,$img); } $this->view('test_canvas'); } private function save_img_real($path, $base64_image_content) { //匹配出图片的格式 if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) { $type = $result[2]; if ($type == 'jpeg') { $type = 'jpg'; } if ($type == 'jpg' || $type == 'gif' || $type == 'png') { if (file_put_contents($path . '.' . $type, base64_decode(str_replace($result[1], '', $base64_image_content)))) { return $type; } else { return false; } } else { return false; } } elseif (preg_match('/^(data:;base64,)/', $base64_image_content, $result)) { $img_data = base64_decode(str_replace($result[1], '', $base64_image_content)); $types = $this->check_image_type($img_data); if ($types) { if (file_put_contents($path . '.' . $types, $img_data)) { return $types; } else { return false; } } else { return false; } } } private function check_image_type($image) { $bits = array( 'jpg' => "\xFF\xD8\xFF", 'gif' => "GIF", 'png' => "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a", ); foreach ($bits as $type => $bit) { if (substr($image, 0, strlen($bit)) === $bit) { return $type; } } return false; }
需要注意的是:图片宽高 250 x 250 太小会失真,我这里就设置成 800 x 800
你的坚持 ------ 终将美好 ~