-
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #13 from remcoder/develop
Release 2.1.0
- Loading branch information
Showing
39 changed files
with
11,526 additions
and
5,306 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,3 +7,4 @@ dist/__tests__ | |
yarn-error.log | ||
.firebase/hosting.* | ||
TODO.md | ||
.DS_Store |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
13 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,268 @@ | ||
/** | ||
* covert canvas to image | ||
* and save the image file | ||
*/ | ||
|
||
var Canvas2Image = function () { | ||
|
||
// check if support sth. | ||
var $support = function () { | ||
var canvas = document.createElement('canvas'), | ||
ctx = canvas.getContext('2d'); | ||
|
||
return { | ||
canvas: !!ctx, | ||
imageData: !!ctx.getImageData, | ||
dataURL: !!canvas.toDataURL, | ||
btoa: !!window.btoa | ||
}; | ||
}(); | ||
|
||
var downloadMime = 'image/octet-stream'; | ||
|
||
function scaleCanvas (canvas, width, height) { | ||
var w = canvas.width, | ||
h = canvas.height; | ||
if (width == undefined) { | ||
width = w; | ||
} | ||
if (height == undefined) { | ||
height = h; | ||
} | ||
|
||
var retCanvas = document.createElement('canvas'); | ||
var retCtx = retCanvas.getContext('2d'); | ||
retCanvas.width = width; | ||
retCanvas.height = height; | ||
retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height); | ||
return retCanvas; | ||
} | ||
|
||
function getDataURL (canvas, type, width, height) { | ||
canvas = scaleCanvas(canvas, width, height); | ||
return canvas.toDataURL(type); | ||
} | ||
|
||
function saveFile (strData, filename) { | ||
var link = document.createElement("a"); | ||
link.download = filename; | ||
link.href = strData; | ||
link.click(); | ||
} | ||
|
||
function genImage(strData) { | ||
var img = document.createElement('img'); | ||
img.src = strData; | ||
return img; | ||
} | ||
function fixType (type) { | ||
type = type.toLowerCase().replace(/jpg/i, 'jpeg'); | ||
var r = type.match(/png|jpeg|bmp|gif/)[0]; | ||
return 'image/' + r; | ||
} | ||
function encodeData (data) { | ||
if (!window.btoa) { throw 'btoa undefined' } | ||
var str = ''; | ||
if (typeof data == 'string') { | ||
str = data; | ||
} else { | ||
for (var i = 0; i < data.length; i ++) { | ||
str += String.fromCharCode(data[i]); | ||
} | ||
} | ||
|
||
return btoa(str); | ||
} | ||
function getImageData (canvas) { | ||
var w = canvas.width, | ||
h = canvas.height; | ||
return canvas.getContext('2d').getImageData(0, 0, w, h); | ||
} | ||
function makeURI (strData, type) { | ||
return 'data:' + type + ';base64,' + strData; | ||
} | ||
|
||
|
||
/** | ||
* create bitmap image | ||
* 按照规则生成图片响应头和响应体 | ||
*/ | ||
var genBitmapImage = function (oData) { | ||
|
||
// | ||
// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx | ||
// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx | ||
// | ||
|
||
var biWidth = oData.width; | ||
var biHeight = oData.height; | ||
var biSizeImage = biWidth * biHeight * 3; | ||
var bfSize = biSizeImage + 54; // total header size = 54 bytes | ||
|
||
// | ||
// typedef struct tagBITMAPFILEHEADER { | ||
// WORD bfType; | ||
// DWORD bfSize; | ||
// WORD bfReserved1; | ||
// WORD bfReserved2; | ||
// DWORD bfOffBits; | ||
// } BITMAPFILEHEADER; | ||
// | ||
var BITMAPFILEHEADER = [ | ||
// WORD bfType -- The file type signature; must be "BM" | ||
0x42, 0x4D, | ||
// DWORD bfSize -- The size, in bytes, of the bitmap file | ||
bfSize & 0xff, bfSize >> 8 & 0xff, bfSize >> 16 & 0xff, bfSize >> 24 & 0xff, | ||
// WORD bfReserved1 -- Reserved; must be zero | ||
0, 0, | ||
// WORD bfReserved2 -- Reserved; must be zero | ||
0, 0, | ||
// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits. | ||
54, 0, 0, 0 | ||
]; | ||
|
||
// | ||
// typedef struct tagBITMAPINFOHEADER { | ||
// DWORD biSize; | ||
// LONG biWidth; | ||
// LONG biHeight; | ||
// WORD biPlanes; | ||
// WORD biBitCount; | ||
// DWORD biCompression; | ||
// DWORD biSizeImage; | ||
// LONG biXPelsPerMeter; | ||
// LONG biYPelsPerMeter; | ||
// DWORD biClrUsed; | ||
// DWORD biClrImportant; | ||
// } BITMAPINFOHEADER, *PBITMAPINFOHEADER; | ||
// | ||
var BITMAPINFOHEADER = [ | ||
// DWORD biSize -- The number of bytes required by the structure | ||
40, 0, 0, 0, | ||
// LONG biWidth -- The width of the bitmap, in pixels | ||
biWidth & 0xff, biWidth >> 8 & 0xff, biWidth >> 16 & 0xff, biWidth >> 24 & 0xff, | ||
// LONG biHeight -- The height of the bitmap, in pixels | ||
biHeight & 0xff, biHeight >> 8 & 0xff, biHeight >> 16 & 0xff, biHeight >> 24 & 0xff, | ||
// WORD biPlanes -- The number of planes for the target device. This value must be set to 1 | ||
1, 0, | ||
// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap | ||
// has a maximum of 2^24 colors (16777216, Truecolor) | ||
24, 0, | ||
// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed | ||
0, 0, 0, 0, | ||
// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps | ||
biSizeImage & 0xff, biSizeImage >> 8 & 0xff, biSizeImage >> 16 & 0xff, biSizeImage >> 24 & 0xff, | ||
// LONG biXPelsPerMeter, unused | ||
0,0,0,0, | ||
// LONG biYPelsPerMeter, unused | ||
0,0,0,0, | ||
// DWORD biClrUsed, the number of color indexes of palette, unused | ||
0,0,0,0, | ||
// DWORD biClrImportant, unused | ||
0,0,0,0 | ||
]; | ||
|
||
var iPadding = (4 - ((biWidth * 3) % 4)) % 4; | ||
|
||
var aImgData = oData.data; | ||
|
||
var strPixelData = ''; | ||
var biWidth4 = biWidth<<2; | ||
var y = biHeight; | ||
var fromCharCode = String.fromCharCode; | ||
|
||
do { | ||
var iOffsetY = biWidth4*(y-1); | ||
var strPixelRow = ''; | ||
for (var x = 0; x < biWidth; x++) { | ||
var iOffsetX = x<<2; | ||
strPixelRow += fromCharCode(aImgData[iOffsetY+iOffsetX+2]) + | ||
fromCharCode(aImgData[iOffsetY+iOffsetX+1]) + | ||
fromCharCode(aImgData[iOffsetY+iOffsetX]); | ||
} | ||
|
||
for (var c = 0; c < iPadding; c++) { | ||
strPixelRow += String.fromCharCode(0); | ||
} | ||
|
||
strPixelData += strPixelRow; | ||
} while (--y); | ||
|
||
var strEncoded = encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) + encodeData(strPixelData); | ||
|
||
return strEncoded; | ||
}; | ||
|
||
/** | ||
* saveAsImage | ||
* @param canvasElement | ||
* @param {String} image type | ||
* @param {Number} [optional] png width | ||
* @param {Number} [optional] png height | ||
*/ | ||
var saveAsImage = function (canvas, width, height, type, filename) { | ||
if ($support.canvas && $support.dataURL) { | ||
if (typeof canvas == "string") { canvas = document.getElementById(canvas); } | ||
if (type == undefined) { type = 'png'; } | ||
type = fixType(type); | ||
if (/bmp/.test(type)) { | ||
var data = getImageData(scaleCanvas(canvas, width, height)); | ||
var strData = genBitmapImage(data); | ||
saveFile(makeURI(strData, downloadMime), filename); | ||
} else { | ||
var strData = getDataURL(canvas, type, width, height); | ||
saveFile(strData.replace(type, downloadMime), filename); | ||
} | ||
} | ||
}; | ||
|
||
var convertToImage = function (canvas, width, height, type) { | ||
if ($support.canvas && $support.dataURL) { | ||
if (typeof canvas == "string") { canvas = document.getElementById(canvas); } | ||
if (type == undefined) { type = 'png'; } | ||
type = fixType(type); | ||
|
||
if (/bmp/.test(type)) { | ||
var data = getImageData(scaleCanvas(canvas, width, height)); | ||
var strData = genBitmapImage(data); | ||
return genImage(makeURI(strData, 'image/bmp')); | ||
} else { | ||
var strData = getDataURL(canvas, type, width, height); | ||
return genImage(strData); | ||
} | ||
} | ||
}; | ||
|
||
|
||
|
||
return { | ||
saveAsImage: saveAsImage, | ||
saveAsPNG: function (canvas, width, height, filename) { | ||
return saveAsImage(canvas, width, height, 'png', filename); | ||
}, | ||
saveAsJPEG: function (canvas, width, height, filename) { | ||
return saveAsImage(canvas, width, height, 'jpeg', filename); | ||
}, | ||
saveAsGIF: function (canvas, width, height, filename) { | ||
return saveAsImage(canvas, width, height, 'gif', filename); | ||
}, | ||
saveAsBMP: function (canvas, width, height, filename) { | ||
return saveAsImage(canvas, width, height, 'bmp', filename); | ||
}, | ||
|
||
convertToImage: convertToImage, | ||
convertToPNG: function (canvas, width, height) { | ||
return convertToImage(canvas, width, height, 'png'); | ||
}, | ||
convertToJPEG: function (canvas, width, height) { | ||
return convertToImage(canvas, width, height, 'jpeg'); | ||
}, | ||
convertToGIF: function (canvas, width, height) { | ||
return convertToImage(canvas, width, height, 'gif'); | ||
}, | ||
convertToBMP: function (canvas, width, height) { | ||
return convertToImage(canvas, width, height, 'bmp'); | ||
} | ||
}; | ||
|
||
}(); |
Oops, something went wrong.