megapix-image插件 使用Canvas压缩图片上传 解决手机端图片上传功能的问题
最近在弄微信端的公众号、订阅号的相关功能,发现原本网页上用的uploadify图片上传功能到手机端有的手机类型上就不能用了,比如iphone,至于为啥我想应该不用多说了吧(uploadify使用flash实现上传的);
经过研究找到了一个手机端比较相对比较好用的插件实现图片上传,那就是megapix-image插件,比uploadify还是好用多了,下面就来上实例吧:
html页面:
<html>
<body>
<input type="file" capture="camera" id="cameraInput" name="cameraInput" style="position:absolute;width:32px;height:32px;opacity:0;filter:alpha(opacity:0);" />
<button id="btnsend" onclick="sendImage()">上 传</button>
<!--图片预览-->
<div id="preview">
<canvas id="myCanvas"></canvas>
<div>
<label id="tip2"></label>
</div>
</div>
</body>
<script type="text/javascript" src="jquery-2.1.1.min.js"></script><!--自己去网上下载-->
<script type="text/javascript" src="megapixImage.js"></script>
<script type="text/javascript" language="javascript">
var fileInput = document.getElementById('cameraInput');
fileInput.onchange = function () {
var file = fileInput.files[0];
var mpImg = new MegaPixImage(file);
var resCanvas1 = document.getElementById('myCanvas');
var _max = 320;
mpImg.render(resCanvas1, {
maxHeight: _max
});
};
function sendImage() {
// 获取 canvas DOM 对象
var canvas = document.getElementById("myCanvas");
// 获取Base64编码后的图像数据,格式是字符串
// "data:image/png;base64,"开头,需要在客户端或者服务器端将其去掉,后面的部分可以直接写入文件。
var dataurl = canvas.toDataURL("image/jpg");
// 为安全 对URI进行编码
// data%3Aimage%2Fpng%3Bbase64%2C 开头
var imagedata = encodeURIComponent(dataurl);
//imagedata = imagedata.replace('data:image/png;base64,', '');
var url = "uploadImgWeixin.php";
// 因为是string,所以服务器需要对数据进行转码,写文件操作等。
// 个人约定,所有http参数名字全部小写
console.log(dataurl);
console.log(imagedata);
var data = {
imagedata: imagedata, _tm:(new Date()).getTime()
};
jQuery.ajax({
url: url,
data: data,
type: "POST",
// 期待的返回值类型
dataType: "json",
complete: function (xhr, result) {
var $tip2 = $("#tip2");
console.log(xhr.responseText);
if (!xhr) {
$tip2.text('网络连接失败!');
return false;
}
var text = xhr.responseText;
if (!text) {
$tip2.text('网络错误!');
return false;
}
var json = eval("(" + text + ")");
if (!json) {
$tip2.text('解析错误!');
return false;
} else {
if(json.status == 1){
$tip2.addClass('green');
alert('图片上传成功');
}else{
$tip2.addClass('error');
alert('图片上传失败');
}
$tip2.text(json.msg);
}
},
});
};
</script>
</html>
megapixImage.js代码:
/**
* Mega pixel image rendering library for iOS6 Safari
*
* Fixes iOS6 Safari's image file rendering issue for large size image (over mega-pixel),
* which causes unexpected subsampling when drawing it in canvas.
* By using this library, you can safely render the image with proper stretching.
*
* Copyright (c) 2012 Shinichi Tomita <shinichi.tomita@gmail.com>
* Released under the MIT license
*/
(function () {
/**
* Detect subsampling in loaded image.
* In iOS, larger images than 2M pixels may be subsampled in rendering.
*/
function detectSubsampling(img) {
var iw = img.naturalWidth, ih = img.naturalHeight;
if (iw * ih > 1024 * 1024) { // subsampling may happen over megapixel image
var canvas = document.createElement('canvas');
canvas.width = canvas.height = 1;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, -iw + 1, 0);
// subsampled image becomes half smaller in rendering size.
// check alpha channel value to confirm image is covering edge pixel or not.
// if alpha value is 0 image is not covering, hence subsampled.
return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
} else {
return false;
}
}
/**
* Detecting vertical squash in loaded image.
* Fixes a bug which squash image vertically while drawing into canvas for some images.
*/
function detectVerticalSquash(img, iw, ih) {
var canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = ih;
var ctx = canvas.getContext('2d');
ctx.drawImage(img, 0, 0);
var data = ctx.getImageData(0, 0, 1, ih).data;
// search image edge pixel position in case it is squashed vertically.
var sy = 0;
var ey = ih;
var py = ih;
while (py > sy) {
var alpha = data[(py - 1) * 4 + 3];
if (alpha === 0) {
ey = py;
} else {
sy = py;
}
py = (ey + sy) >> 1;
}
var ratio = (py / ih);
return (ratio === 0) ? 1 : ratio;
}
/**
* Rendering image element (with resizing) and get its data URL
*/
function renderImageToDataURL(img, options, doSquash) {
var canvas = document.createElement('canvas');
renderImageToCanvas(img, canvas, options, doSquash);
return canvas.toDataURL("image/jpeg", options.quality || 0.8);
}
/**
* Rendering image element (with resizing) into the canvas element
*/
function renderImageToCanvas(img, canvas, options, doSquash) {
var iw = img.naturalWidth, ih = img.naturalHeight;
var width = options.width, height = options.height;
var ctx = canvas.getContext('2d');
ctx.save();
transformCoordinate(canvas, ctx, width, height, options.orientation);
var subsampled = detectSubsampling(img);
if (subsampled) {
iw /= 2;
ih /= 2;
}
var d = 1024; // size of tiling canvas
var tmpCanvas = document.createElement('canvas');
tmpCanvas.width = tmpCanvas.height = d;
var tmpCtx = tmpCanvas.getContext('2d');
var vertSquashRatio = doSquash ? detectVerticalSquash(img, iw, ih) : 1;
var dw = Math.ceil(d * width / iw);
var dh = Math.ceil(d * height / ih / vertSquashRatio);
var sy = 0;
var dy = 0;
while (sy < ih) {
var sx = 0;
var dx = 0;
while (sx < iw) {
tmpCtx.clearRect(0, 0, d, d);
tmpCtx.drawImage(img, -sx, -sy);
ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
sx += d;
dx += dw;
}
sy += d;
dy += dh;
}
ctx.restore();
tmpCanvas = tmpCtx = null;
}
/**
* Transform canvas coordination according to specified frame size and orientation
* Orientation value is from EXIF tag
*/
function transformCoordinate(canvas, ctx, width, height, orientation) {
switch (orientation) {
case 5:
case 6:
case 7:
case 8:
canvas.width = height;
canvas.height = width;
break;
default:
canvas.width = width;
canvas.height = height;
}
switch (orientation) {
case 2:
// horizontal flip
ctx.translate(width, 0);
ctx.scale(-1, 1);
break;
case 3:
// 180 rotate left
ctx.translate(width, height);
ctx.rotate(Math.PI);
break;
case 4:
// vertical flip
ctx.translate(0, height);
ctx.scale(1, -1);
break;
case 5:
// vertical flip + 90 rotate right
ctx.rotate(0.5 * Math.PI);
ctx.scale(1, -1);
break;
case 6:
// 90 rotate right
ctx.rotate(0.5 * Math.PI);
ctx.translate(0, -height);
break;
case 7:
// horizontal flip + 90 rotate right
ctx.rotate(0.5 * Math.PI);
ctx.translate(width, -height);
ctx.scale(-1, 1);
break;
case 8:
// 90 rotate left
ctx.rotate(-0.5 * Math.PI);
ctx.translate(-width, 0);
break;
default:
break;
}
}
/**
* MegaPixImage class
*/
function MegaPixImage(srcImage) {
if (window.Blob && srcImage instanceof Blob) {
var img = new Image();
var URL = window.URL && window.URL.createObjectURL ? window.URL :
window.webkitURL && window.webkitURL.createObjectURL ? window.webkitURL :
null;
if (!URL) { throw Error("No createObjectURL function found to create blob url"); }
img.src = URL.createObjectURL(srcImage);
this.blob = srcImage;
srcImage = img;
}
if (!srcImage.naturalWidth && !srcImage.naturalHeight) {
var _this = this;
srcImage.onload = function () {
var listeners = _this.imageLoadListeners;
if (listeners) {
_this.imageLoadListeners = null;
for (var i = 0, len = listeners.length; i < len; i++) {
listeners[i]();
}
}
};
this.imageLoadListeners = [];
}
this.srcImage = srcImage;
}
/**
* Rendering megapix image into specified target element
*/
MegaPixImage.prototype.render = function (target, options) {
if (this.imageLoadListeners) {
var _this = this;
this.imageLoadListeners.push(function () { _this.render(target, options) });
return;
}
options = options || {};
var imgWidth = this.srcImage.naturalWidth, imgHeight = this.srcImage.naturalHeight,
width = options.width, height = options.height,
maxWidth = options.maxWidth, maxHeight = options.maxHeight,
doSquash = !this.blob || this.blob.type === 'image/jpeg';
if (width && !height) {
height = (imgHeight * width / imgWidth) << 0;
} else if (height && !width) {
width = (imgWidth * height / imgHeight) << 0;
} else {
width = imgWidth;
height = imgHeight;
}
if (maxWidth && width > maxWidth) {
width = maxWidth;
height = (imgHeight * width / imgWidth) << 0;
}
if (maxHeight && height > maxHeight) {
height = maxHeight;
width = (imgWidth * height / imgHeight) << 0;
}
var opt = { width: width, height: height };
for (var k in options) opt[k] = options[k];
var tagName = target.tagName.toLowerCase();
if (tagName === 'img') {
target.src = renderImageToDataURL(this.srcImage, opt, doSquash);
} else if (tagName === 'canvas') {
renderImageToCanvas(this.srcImage, target, opt, doSquash);
}
if (typeof this.onrender === 'function') {
this.onrender(target);
}
};
/**
* Export class to global
*/
if (typeof define === 'function' && define.amd) {
define([], function () { return MegaPixImage; }); // for AMD loader
} else {
this.MegaPixImage = MegaPixImage;
}
})();
php代码:
<?php
$targetFolder = UPLOAD_DIR.date('Y').'/'.date('md').'/';
if(!file_exists($targetFolder)){
mkdir($targetFolder);
}
$imgUrl = $_POST['imagedata'];
$imgData = str_replace(' ', '+', urldecode($imgUrl));
preg_match('/data:([^;]*);base64,(.*)/', $imgData, $matches);
$picUrl = base64_decode($matches[2]);
$t = time().'.jpg';
$save = file_put_contents($targetFolder.$t,$picUrl);
if($save){
$result = array('status'=>1,'url'=>str_replace("/vhost/gaosivip","",$targetFolder.$t),'msg'=>'上传成功');
}else{
$result = array('status'=>0,'msg'=>'上传失败');
}
echo json_encode($result);
?>
megapix-image插件 使用Canvas压缩图片上传 解决手机端图片上传功能的问题的更多相关文章
- js动态改变图片热区坐标,手机端图片热区自适应
<img id='banner1' src="images/banner.jpg" usemap="#banner" border="0&quo ...
- iOS 使用AFN 进行单图和多图上传 摄像头/相册获取图片,压缩图片
图片上传时必要将图片进行压缩,不然会上传失败 首先是同系统相册选择图片和视频.iOS系统自带有UIImagePickerController,可以选择或拍摄图片视频,但是最大的问题是只支持单选,由于项 ...
- laravel上传到七牛图片插件
1.首先引入两个插件 2.在https://developer.qiniu.com/kodo/sdk/1241/php找到安装命令 在终端运行composer require qiniu/php-sd ...
- vue代码上传服务器后背景图片404解决方法
问题:代码上传服务器后,图片404,使用的font-awesome图标也是404 解决办法: 如果你用了vue-cil,那么在build目录下找到utils.js中的ExtractTextPlugin ...
- 使用localResizeIMG3+WebAPI实现手机端图片上传
前言 惯例~惯例~昨天发表的使用OWIN作为WebAPI的宿主..嗯..有很多人问..是不是缺少了什么 - - 好吧,如果你要把OWIN寄宿在其他的地方...代码如下: namespace Conso ...
- 从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能
UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文 ...
- hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images
hTML5实现表单内的上传文件框,上传前预览图片,针刷新预览images, 本例子主要是使用HTML5 的File API,建立一個可存取到该file的url, 一个空的img标签,ID为img0,把 ...
- 【转】asp.net(c#)使用HttpWebRequest附加携带请求参数以post方式模拟上传大文件(以图片为例)到Web服务器端
原文地址:http://docode.top/Article/Detail/10002 目录: 1.Http协议上传文件(以图片为例)请求报文体内容格式 2.完整版HttpWebRequest模拟上传 ...
- php用jquery-ajax上传多张图片限制图片大小
php用jquery-ajax上传多张图片限制图片大小 /** * 上传图片,默认大小限制为3M * @param String $fileInputName * @param number $siz ...
随机推荐
- Maven 使用介绍
1,创建Project 先去官方网站下载一个最新版本http://maven.apache.org/download.cgi. 下载后解压,使用之前最好先将maven的bin目录设置到path环境变量 ...
- Prince2的七大原则(7)
[Prince2科普]Prince2的七大原则(7) 2016-12-12 光环组织级项目管理 按照惯例我们先来回顾一下,PRINCE2七大原则分别是指:持续的业务验证,经验学习,角色与责任,按阶段管 ...
- mysql数据库的一些用法
mysql数据库语句 1.replace into REPLACE INTO (列名1,列名2,列名3) VALUES ('值1','值2','值3'); # 如果数据库中不存在 ...
- -webkit-transform:scale(1.04)放大缩小效果
<p>[鼠标移动进去图片放大一倍效果:运用了-webkit-transform:scale(1.04)效果]</p> 如图:鼠标移动上去的时候图片放大一倍的效果, <!D ...
- python 列表常用操作
例子: list1 = [1, 2, 3, 4, 5, 6, [6, 7, 8,9], 'hi', 'hello', 6] list2 = [7, 8, 1, 2] list3 = ['good', ...
- 《BI项目笔记》多维数据集中度量值设计时的聚合函数
Microsoft SQL Server Analysis Services 提供了几种函数,用来针对包含在度量值组中的维度聚合度量值.默认情况下,度量值按每个维度进行求和.但是,通过 Aggrega ...
- Delphi 文件类型
该内容整理自以下链接 http://www.cnblogs.com/chenyunpeng/archive/2012/08/02/2620513.html 1.DPR: Delphi Project文 ...
- D3.js 做一个简单的图表(条形图)
柱形图是一种最简单的可视化图标,主要有矩形.文字标签.坐标轴组成. 本文为简单起见,只绘制矩形的部分,用以讲解如何使用 D3 在 SVG 画布中绘图. 一. 画布是什么 前几章的处理对象都是 HTML ...
- css-九宫格自适应的实现
高度自适应使用padding 或 padding-bottom + 百分比来实现: 宽度自适应使用width + 百分比来实现. 下面是实现九宫格自适应的代码: <!DOCTYPE html&g ...
- Nmap 使用指南
Namp的英文全称是“Network Mapper”,Namp可用来快速扫描大型网络或是单个主机 nmap主要包括四个方面 主机发现.端口扫描.应用与版本侦测.操作系统侦测 主机发现原理:主机发现的 ...