diff --git a/demo/fitGlyf.html b/demo/fitGlyf.html
new file mode 100644
index 0000000..5770d9d
--- /dev/null
+++ b/demo/fitGlyf.html
@@ -0,0 +1,75 @@
+
+
+
+
+ canvas读取图片
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/demo/js/findBreakPoint.js b/demo/js/findBreakPoint.js
index b5e2e7c..f58d247 100644
--- a/demo/js/findBreakPoint.js
+++ b/demo/js/findBreakPoint.js
@@ -8,7 +8,7 @@ define(
var fitBezier = require('graphics/image/fitBezier');
var findBreakPoints = require('graphics/image/findBreakPoints');
var pathUtil = require('graphics/pathUtil');
- var data = require('demo/../data/image-contours1');
+ var data = require('demo/../data/image-contours2');
var drawPath = require('render/util/drawPath');
var entry = {
diff --git a/demo/js/fitCircle.js b/demo/js/fitCircle.js
index 53f9710..849701e 100644
--- a/demo/js/fitCircle.js
+++ b/demo/js/fitCircle.js
@@ -72,54 +72,6 @@ define(
var radius = dist(points[0], points[1]);
ctx.arc(points[0].x, points[0].y, radius, 0, 180);
ctx.stroke();
-
- // var curvePoints = [];
- // var count = 40;
- // var tSegment = 1 / count;
- // for (var i = 0; i < count; i++) {
- // var t = tSegment * i;
- // curvePoints.push({
- // x: points[0].x * B0(t) + points[1].x * B1(t) + points[2].x * B2(t) + points[3].x * B3(t),
- // y: points[0].y * B0(t) + points[1].y * B1(t) + points[2].y * B2(t) + points[3].y * B3(t)
- // });
- // }
-
- // ctx.fillStyle='green';
- // for (var i = 0; i < count; i++) {
- // ctx.fillRect(curvePoints[i].x, curvePoints[i].y, 2, 2);
- // }
-
- // var result = fitCurve(lang.clone(curvePoints), count);
- // result.unshift(points[0]);
- // //console.log(result);
-
- // ctx.beginPath();
- // ctx.strokeStyle='blue';
- // //ctx.translate(0, 10);
- // ctx.moveTo(result[0].x, result[0].y);
- // for (var i = 1; i < result.length - 1; i+=3) {
- // ctx.bezierCurveTo(result[i].x, result[i].y, result[i + 1].x, result[i + 1].y, result[i + 2].x, result[i + 2].y);
- // ctx.moveTo(result[i + 2].x, result[i + 2].y);
- // }
-
- // ctx.stroke();
-
- // var bezierResult = fitBezier(lang.clone(curvePoints));
- // bezierResult.unshift(curvePoints[0]);
- // ctx.beginPath();
- // ctx.strokeStyle='yellow';
- // //ctx.translate(0, 10);
- // ctx.moveTo(bezierResult[0].x, bezierResult[0].y);
- // var last = bezierResult.length - 1;
- // console.log(bezierResult.length);
- // for (var i = 1; i < last; i+=2) {
- // ctx.quadraticCurveTo(bezierResult[i].x, bezierResult[i].y, bezierResult[i + 1].x, bezierResult[i + 1].y);
- // ctx.moveTo(bezierResult[i + 1].x, bezierResult[i + 1].y);
- // }
-
- // ctx.stroke();
-
- //ctx.translate(0, -20);
}
draw();
diff --git a/demo/js/fitContours.js b/demo/js/fitContours.js
index a439542..f2c4d1c 100644
--- a/demo/js/fitContours.js
+++ b/demo/js/fitContours.js
@@ -6,108 +6,10 @@
define(
function (require) {
- var fitBezier = require('graphics/image/fitBezier');
- var findBreakPoints = require('graphics/image/findBreakPoints');
- var pathUtil = require('graphics/pathUtil');
- var vector = require('graphics/vector');
- var data = require('demo/../data/image-contours1');
+ var fitContour = require('graphics/image/fitContour');
+ var data = require('demo/../data/image-contours2');
var drawPath = require('render/util/drawPath');
-
- var bezierCurvePointsArray = [];
-
- function fitContour(data) {
-
- data = pathUtil.scale(data, 10);
- var breakPoints = findBreakPoints(data);
-
- breakPoints.forEach(function (p) {
- console.log(p.right);
- });
-
- var resultContour = [];
- var isLast;
- var start;
- var end;
- var tHat1Point;
- for (var i = 0, l = breakPoints.length; i < l; i++) {
- isLast = i === l - 1;
- start = breakPoints[i];
- end = breakPoints[ isLast ? 0 : i + 1];
-
- resultContour.push({
- x: start.x,
- y: start.y,
- onCurve: true
- });
-
- if (start.right !== 1) {
-
- if (isLast) {
- var curvePoints = data.slice(start.index).concat(data.slice(0, end.index));
- }
- else {
- var curvePoints = data.slice(start.index, end.index + 1);
- }
-
- var bezierCurvePoints = [];
- var curvePointsLast = curvePoints.length - 1;
-
- if (curvePoints.length > 200) {
- var derive = Math.floor(curvePoints.length / 10);
- bezierCurvePoints = curvePoints.filter(function (p, index) {
- return index === 0 || index === curvePointsLast || p.index % derive === 0;
- });
- }
- else if (curvePoints.length > 30) {
- var derive = Math.floor(curvePoints.length / 5);
- bezierCurvePoints = curvePoints.filter(function (p, index) {
- return index === 0 || index === curvePointsLast || p.index % derive === 0;
- });
- }
- else {
- bezierCurvePoints = curvePoints.filter(function (p, index) {
- return index === 0 || index === curvePointsLast || p.index % 5 === 0;
- });
- }
-
- if ((start.tangency || start.inflexion) && tHat1Point) {
- tHat1 = vector.normalize({
- x: start.x - tHat1Point.x,
- y: start.y - tHat1Point.y
- });
- }
- else {
- tHat1 = null;
- }
-
- bezierCurvePoints.forEach(function (p) {
- bezierCurvePointsArray.push(p);
- });
-
- var bezierCurve = fitBezier(bezierCurvePoints, 10, tHat1);
- if (bezierCurve.length) {
- bezierCurve.forEach(function (p) {
- resultContour.push(p);
- });
- tHat1Point = bezierCurve[bezierCurve.length - 2];
- }
- else {
- tHat1Point = null;
- }
- }
- else {
- tHat1Point = start;
- }
- }
-
- resultContour = pathUtil.scale(resultContour, 0.1);
- data = pathUtil.scale(data, 0.1);
-
- return resultContour;
- }
-
-
var entry = {
/**
@@ -132,13 +34,9 @@ define(
$('#points').html(html);
html = '';
- bezierCurvePointsArray.forEach(function (p) {
- html += '';
- });
-
var ctx = $('#canvas').get(0).getContext('2d');
- ctx.strokeStyle = 'yellow';
+ ctx.strokeStyle = 'pink';
contours.forEach(function (contour) {
for (var i = 0, l = contour.length; i < l; i++) {
diff --git a/demo/js/fitGlyf.js b/demo/js/fitGlyf.js
new file mode 100644
index 0000000..b0c4041
--- /dev/null
+++ b/demo/js/fitGlyf.js
@@ -0,0 +1,119 @@
+/**
+ * @file 拟合图像字形
+ * @author mengke01(kekee000@gmail.com)
+ */
+
+define(
+ function (require) {
+
+ var fitContour = require('graphics/image/fitContour');
+ var image2Values = require('graphics/image/image2Values');
+ var findContours = require('graphics/image/findContours');
+ var computeBoundingBox = require('graphics/computeBoundingBox');
+ var pathAdjust = require('graphics/pathAdjust');
+ var drawPath = require('render/util/drawPath');
+ var data = require('demo/../data/image-contours2');
+
+ var editor = require('editor/main');
+
+ var ctx = null;
+
+ function fitGlyf(data) {
+ var html = '';
+ var contours = [];
+ data.forEach(function(contour) {
+ contour.forEach(function (p) {
+ html += '';
+ });
+ contours.push(fitContour(contour));
+ });
+
+ $('#points').html(html);
+
+ html = '';
+ ctx.beginPath();
+ ctx.clearRect(0,0, 1000, 1000);
+ ctx.strokeStyle = 'pink';
+ contours.forEach(function (contour) {
+ for (var i = 0, l = contour.length; i < l; i++) {
+ html += '';
+ }
+ drawPath(ctx, contour);
+ });
+
+ ctx.stroke();
+
+ $('#points-break').html(html);
+
+ var bound = computeBoundingBox.computePath.apply(null, contours);
+
+ window.editor.setFont({
+ contours: contours.map(function (contour) {
+ pathAdjust(contour, 1, -1);
+ pathAdjust(contour, 1, 1, 0, bound.height);
+ return contour;
+ })
+ });
+ }
+
+ function findImageContours(imgData) {
+ var result = image2Values(imgData);
+ var contours = findContours(result);
+
+ fitGlyf(contours);
+ }
+
+
+
+ function onUpFileChange(e) {
+ var file = e.target.files[0];
+ var reader = new FileReader();
+ reader.onload = function(e) {
+
+ var image = new Image();
+ image.onload = function () {
+ ctx.clearRect(0,0, 1000, 1000);
+ ctx.drawImage(image, 0, 0, image.width, image.height);
+ findImageContours(ctx.getImageData(0, 0, image.width, image.height));
+ };
+
+ image.src = e.target.result;
+ }
+
+ reader.onerror = function(e) {
+ console.error(e);
+ };
+
+ reader.readAsDataURL(file);
+ }
+
+ var entry = {
+
+ /**
+ * 初始化
+ */
+ init: function () {
+
+ window.editor = editor.create($('#render-view').get(0));
+
+ var upFile = document.getElementById('upload-file');
+ upFile.addEventListener('change', onUpFileChange);
+
+ ctx = $('#canvas').get(0).getContext('2d');
+
+ if (data) {
+ data.forEach(function(contour) {
+ contour.splice(contour.length - 1, 1);
+ });
+
+ fitGlyf(data);
+ }
+ }
+
+ };
+
+ entry.init();
+
+ return entry;
+ }
+);
diff --git a/src/graphics/image/findBreakPoints.js b/src/graphics/image/findBreakPoints.js
index 8b811b7..9fc600f 100644
--- a/src/graphics/image/findBreakPoints.js
+++ b/src/graphics/image/findBreakPoints.js
@@ -30,7 +30,7 @@ define(
}
function isLine(p0, p1, p) {
- return 1 - absCos(p0, p1, p) < 0.01;
+ return 1 - absCos(p0, p1, p) < 0.004;
}
function isPerfectLine(p0, p1, p) {
@@ -212,7 +212,9 @@ define(
breakPoints = removeInflexionPoint(breakPoints, contour);
- return breakPoints;
+ return breakPoints.sort(function (a, b) {
+ return a.index - b.index;
+ });
}
/**
diff --git a/src/graphics/image/findContours.js b/src/graphics/image/findContours.js
index 64a8094..a0a5d9b 100644
--- a/src/graphics/image/findContours.js
+++ b/src/graphics/image/findContours.js
@@ -99,7 +99,7 @@ define(
x: x,
y: y
}, true);
- contours.push(contour);
+ contour && contours.push(contour);
}
}
@@ -111,7 +111,7 @@ define(
x: x - 1,
y: y
}, true);
- contours.push(contour.reverse());
+ contour && contours.push(contour.reverse());
}
}
}
diff --git a/src/graphics/image/fitContour.js b/src/graphics/image/fitContour.js
new file mode 100644
index 0000000..1699d76
--- /dev/null
+++ b/src/graphics/image/fitContour.js
@@ -0,0 +1,105 @@
+/**
+ * @file 根据关键点数据拟合轮廓
+ * @author mengke01(kekee000@gmail.com)
+ */
+
+
+define(
+ function (require) {
+
+ var fitBezier = require('graphics/image/fitBezier');
+ var findBreakPoints = require('graphics/image/findBreakPoints');
+ var pathUtil = require('graphics/pathUtil');
+ var vector = require('graphics/vector');
+
+
+ function fitContour(data) {
+
+ data = pathUtil.scale(data, 10);
+
+ var breakPoints = findBreakPoints(data);
+
+ var resultContour = [];
+ var isLast;
+ var start;
+ var end;
+ var curvePoints;
+ var tHat1Point;
+
+ for (var i = 0, l = breakPoints.length; i < l; i++) {
+ isLast = i === l - 1;
+ start = breakPoints[i];
+ end = breakPoints[ isLast ? 0 : i + 1];
+
+ resultContour.push({
+ x: start.x,
+ y: start.y,
+ onCurve: true
+ });
+
+ if (start.right !== 1) {
+
+ if (isLast) {
+ curvePoints = data.slice(start.index).concat(data.slice(0, end.index));
+ }
+ else {
+ curvePoints = data.slice(start.index, end.index + 1);
+ }
+
+ var bezierCurvePoints = [];
+ var curvePointsLast = curvePoints.length - 1;
+
+ if (curvePoints.length > 200) {
+ var derive = Math.floor(curvePoints.length / 20);
+ bezierCurvePoints = curvePoints.filter(function (p, index) {
+ return index === 0 || index === curvePointsLast || p.index % derive === 0;
+ });
+ }
+ else if (curvePoints.length > 40) {
+ var derive = Math.floor(curvePoints.length / 10);
+ bezierCurvePoints = curvePoints.filter(function (p, index) {
+ return index === 0 || index === curvePointsLast || p.index % derive === 0;
+ });
+ }
+ else {
+ bezierCurvePoints = curvePoints.filter(function (p, index) {
+ return index === 0 || index === curvePointsLast || p.index % 5 === 0;
+ });
+ }
+
+ if (start.tangency && tHat1Point) {
+ tHat1 = vector.normalize({
+ x: start.x - tHat1Point.x,
+ y: start.y - tHat1Point.y
+ });
+ }
+ else {
+ tHat1 = null;
+ }
+
+ var bezierCurve = fitBezier(bezierCurvePoints, 10, tHat1);
+ if (bezierCurve.length) {
+ bezierCurve.forEach(function (p) {
+ resultContour.push(p);
+ });
+ tHat1Point = bezierCurve[bezierCurve.length - 2];
+ }
+ else {
+ tHat1Point = null;
+ }
+ }
+ else {
+ tHat1Point = start;
+ }
+ }
+
+ resultContour = pathUtil.scale(resultContour, 0.1);
+
+ data = pathUtil.scale(data, 0.1);
+
+ return resultContour;
+ }
+
+ return fitContour;
+ }
+);
diff --git a/src/graphics/image/fitCurve.js b/src/graphics/image/fitCurve.js
index d5885b1..b4667ff 100644
--- a/src/graphics/image/fitCurve.js
+++ b/src/graphics/image/fitCurve.js
@@ -267,8 +267,8 @@ define(
/* Generate control vertices for Q'' */
for (i = 0; i <= 1; i++) {
Q2[i] = {
- x: (Q[i + 1].x - Q[i].x) * 2.0,
- y: (Q[i + 1].y - Q[i].y) * 2.0
+ x: (Q[i + 1].x - Q[i].x) * 6.0,
+ y: (Q[i + 1].y - Q[i].y) * 6.0
};
}
diff --git a/test/ecomfe.png b/test/ecomfe.png
new file mode 100644
index 0000000..1278d09
Binary files /dev/null and b/test/ecomfe.png differ