<!DOCTYPE html >
<html>
<head>
<title>通過Canvas及File API縮放並上傳圖片</title>
<script src="/Scripts/Jquery/jquery-1.8.3.min.js" type="text/javascript"></script>
<script src="/Scripts/MegaPixImage/MegaPixImage.js" type="text/javascript"></script>
<script type="text/javascript" language="javascript">
function sendImage() {
// 獲取 canvas DOM 物件
var canvas = document.getElementById("myCanvas");
// 獲取Base64編碼後的影像資料,格式是字串
// "data:image/png;base64,"開頭,需要在客戶端或者伺服器端將其去掉,後面的部分可以直接寫入檔案。
var dataurl = canvas.toDataURL("image/png");
// 為安全 對URI進行編碼
// data%3Aimage%2Fpng%3Bbase64%2C 開頭
var imagedata = encodeURIComponent(dataurl);
//imagedata = imagedata.replace('data:image/png;base64,', '');
var url = "/APPCommon/SavePostCanvasImage";
// 因為是string,所以伺服器需要對資料進行轉碼,寫檔案操作等。
// 個人約定,所有http引數名字全部小寫
console.log(dataurl);
console.log(imagedata);
var data = {
imagename: "myImage.png",
imagedata: imagedata
};
jQuery.ajax({
url: url,
data: data,
type: "POST",
// 期待的返回值型別
dataType: "json",
complete: function (xhr, result) {
console.log(xhr.responseText);
var $tip2 = $("#tip2");
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 {
$tip2.text(json.Result);
}
}
});
};
</script>
</head>
<body>
<div>
<input type="file" capture="camera" accept="image/*" id="cameraInput" name="cameraInput"
class="sign_file" />
<canvas id="myCanvas"></canvas>
<button id="btnsend" onclick="sendImage()">上 傳</button>
<div>
<label id="tip2">
</label>
</div>
</div>
<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
});
// var resCanvas2 = document.getElementById('resultCanvas2');
// mpImg.render(resCanvas2, {
// maxWidth: 300,
// maxHeight: 300,
// orientation: 6
// });
};
</script>
</body>
</html>
/**
* 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;
}
})();