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 ...
随机推荐
- Linux之curl命令详解
url命令是一个功能强大的网络工具,它能够通过http.ftp等方式下载文件,也能够上传文件.其实curl远不止前面所说的那些功能,大家可以通过man curl阅读手册页获取更多的信息.类似的工具还有 ...
- if,else语句的运用
1.求解一元二次方程 Console.WriteLine("求解一元二次方程:a*x*x+b*x+c=0"); Console.Write("请输入 a="); ...
- sftp 设置仅能访问自己目录的用户
1. 创建一个目录,owner为root,权限为750或755,此处为 /home/test01 添加一个用户test01,home目录设置为 /home/test01 再创建一个子目录用于用户上传: ...
- 复旦大学2014--2015学年第二学期高等代数II期末考试情况分析
一.期末考试成绩班级前几名 钱列(100).王华(92).李笑尘(92).金羽佳(91).李卓凡(91).包振航(91).董麒麟(90).张钧瑞(90).陆毕晨(90).刘杰(90).黄成晗(90). ...
- Python3基础 int(input())输入数字并产生一个int类型变量
镇场诗:---大梦谁觉,水月中建博客.百千磨难,才知世事无常.---今持佛语,技术无量愿学.愿尽所学,铸一良心博客.------------------------------------------ ...
- C#浅拷贝与深拷贝区别
也许会有人这样解释C# 中浅拷贝与深拷贝区别: 浅拷贝是对引用类型拷贝地址,对值类型直接进行拷贝. 不能说它完全错误,但至少还不够严谨.比如:string 类型咋说? 其实,我们可以通过实践来寻找答案 ...
- javascript this在事件中的应用
this关键字在javascript中是非常强大的,但是如果你不清楚它是怎么工作的就很难使用它. function dosomething(){ this.style.color="#fff ...
- iOS - iOS 适配
前言 什么是适配: 适应.兼容各种不同的情况. iOS 开发中,适配的常见种类: 1)系统适配, 针对不同版本的操作系统进行适配. 2)屏幕适配,针对不同大小的屏幕尺寸进行适配. iPhone 的尺寸 ...
- ie兼容问题整理
1.连续发请求问题 * jquery(document).ready(function(){}) * 连续发请求ie8出问题,被拦截问题,url后边加时间戳 * 例 url : url+ ...
- 点击datagrid弹出ldhdialog,点击弹出框的按钮,关闭且刷新datagrid
datagrid里的js这么写 //点击添加按钮触发 function superadd(title,addurl,gname,width,height) { gridname=gname; crea ...