相關鏈接 參考文章、 canvas 轉 圖片
<input type="button" value="download" id="dd">
<div id="dropTarget"></div>
<div id="font-container"></div>
</body>
</html>
<script
src="http://code.jquery.com/jquery-1.12.4.min.js"
integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ="
crossorigin="anonymous"></script>
<script src="https://cdn.bootcss.com/jszip/3.2.0/jszip.min.js"></script>
<script src="FileSaver.js"></script>
#dropTarget {
width: 300px;
height: 200px;
background-color: red;
}
"use strict";
/** @param {string=} message */
function assert(condition, message) {
message = message || "Assertion failed";
if (!condition) {
alert(message);
throw message;
}
}
/** @constructor */
function BinaryReader(arrayBuffer) {
assert(arrayBuffer instanceof ArrayBuffer);
this.pos = 0;
this.data = new Uint8Array(arrayBuffer);
}
BinaryReader.prototype = {
seek: function (pos) {
assert(pos >= 0 && pos <= this.data.length);
var oldPos = this.pos;
this.pos = pos;
return oldPos;
},
tell: function () {
return this.pos;
},
getUint8: function () {
assert(this.pos < this.data.length);
return this.data[this.pos++];
},
getUint16: function () {
return ((this.getUint8() << 8) | this.getUint8()) >>> 0;
},
getUint32: function () {
return this.getInt32() >>> 0;
},
getInt16: function () {
var result = this.getUint16();
if (result & 0x8000) {
result -= (1 << 16);
}
return result;
},
getInt32: function () {
return ((this.getUint8() << 24) |
(this.getUint8() << 16) |
(this.getUint8() << 8) |
(this.getUint8()));
},
getFword: function () {
return this.getInt16();
},
get2Dot14: function () {
return this.getInt16() / (1 << 14);
},
getFixed: function () {
return this.getInt32() / (1 << 16);
},
getString: function (length) {
var result = "";
for (var i = 0; i < length; i++) {
result += String.fromCharCode(this.getUint8());
}
return result;
},
getDate: function () {
var macTime = this.getUint32() * 0x100000000 + this.getUint32();
var utcTime = macTime * 1000 + Date.UTC(1904, 1, 1);
return new Date(utcTime);
}
};
/** @constructor */
function TrueTypeFont(arrayBuffer) {
this.file = new BinaryReader(arrayBuffer);
this.tables = this.readOffsetTables(this.file);
this.readHeadTable(this.file);
this.length = this.glyphCount();
}
TrueTypeFont.prototype = {
readOffsetTables: function (file) {
var tables = {};
this.scalarType = file.getUint32();
var numTables = file.getUint16();
this.searchRange = file.getUint16();
this.entrySelector = file.getUint16();
this.rangeShift = file.getUint16();
for (var i = 0; i < numTables; i++) {
var tag = file.getString(4);
tables[tag] = {
checksum: file.getUint32(),
offset: file.getUint32(),
length: file.getUint32()
};
if (tag !== 'head') {
assert(this.calculateTableChecksum(file, tables[tag].offset,
tables[tag].length) === tables[tag].checksum);
}
}
return tables;
},
calculateTableChecksum: function (file, offset, length) {
var old = file.seek(offset);
var sum = 0;
var nlongs = ((length + 3) / 4) | 0;
while (nlongs--) {
sum = (sum + file.getUint32() & 0xffffffff) >>> 0;
}
file.seek(old);
return sum;
},
readHeadTable: function (file) {
assert("head" in this.tables);
file.seek(this.tables["head"].offset);
this.version = file.getFixed();
this.fontRevision = file.getFixed();
this.checksumAdjustment = file.getUint32();
this.magicNumber = file.getUint32();
assert(this.magicNumber === 0x5f0f3cf5);
this.flags = file.getUint16();
this.unitsPerEm = file.getUint16();
this.created = file.getDate();
this.modified = file.getDate();
this.xMin = file.getFword();
this.yMin = file.getFword();
this.xMax = file.getFword();
this.yMax = file.getFword();
this.macStyle = file.getUint16();
this.lowestRecPPEM = file.getUint16();
this.fontDirectionHint = file.getInt16();
this.indexToLocFormat = file.getInt16();
this.glyphDataFormat = file.getInt16();
},
glyphCount: function () {
assert("maxp" in this.tables);
var old = this.file.seek(this.tables["maxp"].offset + 4);
var count = this.file.getUint16();
this.file.seek(old);
return count;
},
getGlyphOffset: function (index) {
assert("loca" in this.tables);
var table = this.tables["loca"];
var file = this.file;
var offset, old;
if (this.indexToLocFormat === 1) {
old = file.seek(table.offset + index * 4);
offset = file.getUint32();
} else {
old = file.seek(table.offset + index * 2);
offset = file.getUint16() * 2;
}
file.seek(old);
return offset + this.tables["glyf"].offset;
},
readGlyphs: function (file) {
assert("glyf" in this.tables);
var glyphTable = this.tables["glyf"];
file.seek(glyphTable.offset);
var glyphs = [];
while (file.tell() < glyphTable.offset + glyphTable.length) {
glyphs.push(this.readGlyph(file));
while (file.tell() & 1) {
file.getUint8();
}
}
return glyphs;
},
readGlyph: function (index) {
var offset = this.getGlyphOffset(index);
var file = this.file;
if (offset >= this.tables["glyf"].offset + this.tables["glyf"].length) {
return null;
}
assert(offset >= this.tables["glyf"].offset);
assert(offset < this.tables["glyf"].offset + this.tables["glyf"].length);
file.seek(offset);
var glyph = {
numberOfContours: file.getInt16(),
xMin: file.getFword(),
yMin: file.getFword(),
xMax: file.getFword(),
yMax: file.getFword()
};
assert(glyph.numberOfContours >= -1);
if (glyph.numberOfContours === -1) {
this.readCompoundGlyph(file, glyph);
} else {
this.readSimpleGlyph(file, glyph);
}
return glyph;
},
readSimpleGlyph: function (file, glyph) {
var ON_CURVE = 1,
X_IS_BYTE = 2,
Y_IS_BYTE = 4,
REPEAT = 8,
X_DELTA = 16,
Y_DELTA = 32;
glyph.type = "simple";
glyph.contourEnds = [];
var points = glyph.points = [];
for (var i = 0; i < glyph.numberOfContours; i++) {
glyph.contourEnds.push(file.getUint16());
}
// skip over intructions
file.seek(file.getUint16() + file.tell());
if (glyph.numberOfContours === 0) {
return;
}
var numPoints = Math.max.apply(null, glyph.contourEnds) + 1;
var flags = [];
for (i = 0; i < numPoints; i++) {
var flag = file.getUint8();
flags.push(flag);
points.push({
onCurve: (flag & ON_CURVE) > 0
});
if (flag & REPEAT) {
var repeatCount = file.getUint8();
assert(repeatCount > 0);
i += repeatCount;
while (repeatCount--) {
flags.push(flag);
points.push({
onCurve: (flag & ON_CURVE) > 0
});
}
}
}
function readCoords(name, byteFlag, deltaFlag, min, max) {
var value = 0;
for (var i = 0; i < numPoints; i++) {
var flag = flags[i];
if (flag & byteFlag) {
if (flag & deltaFlag) {
value += file.getUint8();
} else {
value -= file.getUint8();
}
} else if (~flag & deltaFlag) {
value += file.getInt16();
} else {
// value is unchanged.
}
points[i][name] = value;
}
}
readCoords("x", X_IS_BYTE, X_DELTA, glyph.xMin, glyph.xMax);
readCoords("y", Y_IS_BYTE, Y_DELTA, glyph.yMin, glyph.yMax);
},
readCompoundGlyph: function (file, glyph) {
var ARG_1_AND_2_ARE_WORDS = 1,
ARGS_ARE_XY_VALUES = 2,
ROUND_XY_TO_GRID = 4,
WE_HAVE_A_SCALE = 8,
// RESERVED = 16
MORE_COMPONENTS = 32,
WE_HAVE_AN_X_AND_Y_SCALE = 64,
WE_HAVE_A_TWO_BY_TWO = 128,
WE_HAVE_INSTRUCTIONS = 256,
USE_MY_METRICS = 512,
OVERLAP_COMPONENT = 1024;
glyph.type = "compound";
glyph.components = [];
var flags = MORE_COMPONENTS;
while (flags & MORE_COMPONENTS) {
var arg1, arg2;
flags = file.getUint16();
var component = {
glyphIndex: file.getUint16(),
matrix: {
a: 1, b: 0, c: 0, d: 1, e: 0, f: 0
}
};
if (flags & ARG_1_AND_2_ARE_WORDS) {
arg1 = file.getInt16();
arg2 = file.getInt16();
} else {
arg1 = file.getUint8();
arg2 = file.getUint8();
}
if (flags & ARGS_ARE_XY_VALUES) {
component.matrix.e = arg1;
component.matrix.f = arg2;
} else {
component.destPointIndex = arg1;
component.srcPointIndex = arg2;
}
if (flags & WE_HAVE_A_SCALE) {
component.matrix.a = file.get2Dot14();
component.matrix.d = component.matrix.a;
} else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
component.matrix.a = file.get2Dot14();
component.matrix.d = file.get2Dot14();
} else if (flags & WE_HAVE_A_TWO_BY_TWO) {
component.matrix.a = file.get2Dot14();
component.matrix.b = file.get2Dot14();
component.matrix.c = file.get2Dot14();
component.matrix.d = file.get2Dot14();
}
glyph.components.push(component);
}
if (flags & WE_HAVE_INSTRUCTIONS) {
file.seek(file.getUint16() + file.tell());
}
},
drawGlyph: function (index, ctx) {
var glyph = this.readGlyph(index);
if (glyph === null || glyph.type !== "simple") {
return false;
}
var p = 0,
c = 0,
first = 1;
while (p < glyph.points.length) {
var point = glyph.points[p];
if (first === 1) {
ctx.moveTo(point.x, point.y);
first = 0;
} else {
ctx.lineTo(point.x, point.y);
}
if (p === glyph.contourEnds[c]) {
c += 1;
first = 1;
}
p += 1;
}
return true;
}
};
var imgUrl = [];
function ShowTtfFile(arrayBuffer) {
var font = new TrueTypeFont(arrayBuffer);
var width = font.xMax - font.xMin;
var height = font.yMax - font.yMin;
var scale = 64 / font.unitsPerEm;
var container = document.getElementById("font-container");
while (container.firstChild) {
container.removeChild(container.firstChild);
}
for (var i = 0; i < font.length; i++) {
var canvas = document.createElement("canvas");
canvas.style.border = "1px solid gray";
canvas.width = width * scale;
canvas.height = height * scale;
var ctx = canvas.getContext("2d");
ctx.scale(scale, -scale);
ctx.translate(-font.xMin, -font.yMin - height);
ctx.fillStyle = "#000000";
ctx.beginPath();
if (font.drawGlyph(i, ctx)) {
ctx.fill();
// container.appendChild(canvas);
var image = new Image();
image.src = canvas.toDataURL("image/png");
imgUrl.push(image.src);
container.appendChild(image);
// download('png' + i, image.src);
}
}
// packageImages();
}
var dropTarget = document.getElementById("dropTarget");
dropTarget.ondragover = function (e) {
e.preventDefault();
};
dropTarget.ondrop = function (e) {
e.preventDefault();
if (!e.dataTransfer || !e.dataTransfer.files) {
alert("Your browser didn't include any files in the drop event");
return;
}
var reader = new FileReader();
reader.readAsArrayBuffer(e.dataTransfer.files[0]);
reader.onload = function (e) {
ShowTtfFile(reader.result);
};
};
/*function download(name, href) {
setTimeout(function () {
console.log(name);
var a = document.createElement("a"), //創建a標籤
e = document.createEvent("MouseEvents"); //創建鼠標事件對象
e.initEvent("click", false, false); //初始化事件對象
a.href = href; //設置下載地址
a.download = name; //設置下載文件名
a.dispatchEvent(e); //給指定的元素,執行事件click事件
}, 1000);
}*/
/*function packageImages() {
$('#status').text('處理中。。。。。');
var imgBase64 = [];
var imageSuffix = [];//圖片後綴
var zip = new JSZip();
zip.file("readme.txt", "案件詳情資料\n");
var img = zip.folder("images");
for (var i = 0; i < imgUrl.length; i++) {
var src = imgUrl[i];
var suffix = src.substring(src.lastIndexOf("."));
imageSuffix.push(suffix);
getBase64(src).then(function (base64) {
imgBase64.push(base64.substring(22));
}, function (err) {
console.log(err);//打印異常信息
});
}
function tt() {
setTimeout(function () {
if (imgUrl.length == imgBase64.length) {
for (var i = 0; i < imgUrl.length; i++) {
img.file('png' + imageSuffix[i], imgBase64[i], {base64: true});
}
zip.generateAsync({type: "blob"}).then(function (content) {
// see FileSaver.js
status = saveAs(content, "images.zip");
layer.closeAll();
layer.msg("導出成功!");
});
} else {
tt();
}
}, 100);
}
tt();
}
//傳入圖片路徑,返回base64
function getBase64(img) {
function getBase64Image(img, width, height) {
//width、height調用時傳入具體像素值,控制大小 ,不傳則默認圖像大小
var canvas = document.createElement("canvas");
canvas.width = width ? width : img.width;
canvas.height = height ? height : img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
var dataURL = canvas.toDataURL();
return dataURL;
}
var image = new Image();
image.crossOrigin = 'Anonymous';
image.src = img;
var deferred = $.Deferred();
if (img) {
image.onload = function () {
deferred.resolve(getBase64Image(image));//將base64傳給done上傳處理
}
return deferred.promise();//問題要讓onload完成後再return sessionStorage['imgTest']
}
}*/
document.getElementById('dd').onclick = function () {
var ii = 0;
function sleep(d) {
for (var t = Date.now(); Date.now() - t <= d;) ;
}
function download(src) {
var $a = document.createElement('a');
$a.setAttribute("href", src);
$a.setAttribute("download", 'ttf2img' + ii);
ii++;
var evObj = document.createEvent('MouseEvents');
evObj.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, true, false, 0, null);
$a.dispatchEvent(evObj);
};
var res = document.getElementsByTagName("img");
console.log(res.length);
var ans = [];
var sum = 0;
for (var i = 0; i < res.length; i++) {
var temp = res[i].src;
// if (temp.search("280x373") !== -1) {
ans[sum++] = temp;
// }
}
for (var i = 0; i < ans.length; i++) {
// ans[i] = ans[i].replace("280x373", "760x1013");
//console.log(ans[i]);
sleep(100);
download(ans[i]);
}
}