Рассчитать размер шрифта на основе разрешения изображения и размера пользовательского ввода - PullRequest
0 голосов
/ 05 марта 2020

У меня есть проект и проблема с масштабированием шрифта на основе canvas. js.

Сведения о проекте:

  • на основе node.js
  • используйте vue. js / javascript
  • convas для vue

Проблема:

Я взял проект у бывшего сотрудника в Работа. У пользователя есть возможность загрузить изображение, которое отображается на холсте в качестве фона (это изделие из дерева). Чем он может загружать изображения или тексты и размещать их на них. Когда пользователь загружает изображение продукта, он может указать его высоту и ширину в виде значения (см).

Затем он может разместить на нем текстовый элемент (холст) и установить размер шрифта (в «pt»). «). Проблема заключается в том, что я должен масштабировать шрифт относительно размера продукта из пользовательского ввода (24 см х 21 см) на фоне продукта.

Имеются следующие значения:

  • Фоновое изображение с разрешением: 1200x950px
  • Размер продукта: 24x21cm
  • Размер шрифта на выбор: 14 , 16, .. (в pt) - думаю, что я должен установить значения для canvas в px, но это можно вычислить.

Как я могу масштабировать шрифт относительно значений, как только На самом деле продукт выгравирован, имеет правильный размер шрифта, а также правильно отображается на холсте?

Мой бывший сотрудник должен оставить расчет в проекте (размер шрифта в мм):

let fontFactor = (высота изображения [950px] * 10) / высота продукта [21 см] * 100

let fontSize (в мм) = fontValue [16,18 .. ] * fontFactor

1 Ответ

0 голосов
/ 06 марта 2020

Линейный масштаб

Прямое масштабирование соответствует заданному размеру, если вы установите sh соотношение между пикселями и масштабом, в котором вы работаете.

Например, размер изображения и репрезентативный физический размер могут быть выражены как

const imageSize = {
    cm: {width: 24, height: 21},
    px: {width: 1200, height: 950},
    cm2px: {width: 1200 / 24, height: 950 / 21},
    px2cm: {width: 24 / 1200, height: 21 / 950},
};

Задание размера холста и физического и масштаб преобразования между ними.

При этом и зная масштаб Соотношение между «Точками» и «см» при 1pt = 0,0353 позволяет масштабировать текст холста в соответствии с размером точек в сантиметровой шкале холста.

Для масштабирования и рендеринга от «px» до «point» с указанными выше сведениями

    const pt2cm = 0.0353;
    const textPointSize = 38;

    ctx.font = textPointSize + "px arial"; // In px (pixels)

    const xScale = pt2cm * imageSize.cm2px.width;
    const yScale = pt2cm * imageSize.cm2px.height;
    ctx.setTransform(xScale, 0, 0, yScale, 100, 100);

    ctx.fillText("38pt text", 0, 0);

Пример

В примере создается холст и др aws см сетка. Затем dr aws шрифт на холсте разных размеров.

Функция drawText принимает размер шрифта в точках и положение текста в см

Высота текста 38pt составляет около 13 мм в масштабе изображения холста с использованием размера точки 0,0352778. см

const ctx = canvas.getContext("2d");

const imageSize = {
    cm: {width: 24, height: 21},
    px: {width: 1200, height: 950},
    cm2px: {width: 1200 / 24, height: 950 / 21},
    px2cm: {width: 24 / 1200, height: 21 / 950},
};
const pt2cm = 0.0352778;

canvas.width = imageSize.px.width;
canvas.height = imageSize.px.height;
drawGrid();

for (let i = 10; i < 40; i += 4) {
    drawText("Test text "+i+"pt", i, 3, 1 + (i - 10) / 2);
}

function drawText(text, sizePt, xCm, yCm) {
    const x = imageSize.cm2px.width * xCm;
    const y = imageSize.cm2px.height * yCm;
    ctx.font = sizePt+"px Arial";
    ctx.textAlign = "left";
    ctx.textBaseline = "top"
    ctx.fillStyle = "#000";
    const xs = pt2cm * imageSize.cm2px.width;
    const ys = pt2cm * imageSize.cm2px.height;
    ctx.setTransform(xs, 0, 0, ys, x, y);
    ctx.fillText(text, 0, 0);
    ctx.setTransform(1,0,0,1,0,0);
}














// Draws a grid
function drawGrid() {
    const w = imageSize.px.width;
    const h = imageSize.px.height;
    const sx = imageSize.cm2px.width;
    const sy = imageSize.cm2px.height;
    ctx.globalAlpha = 0.3;
    ctx.fillStyle = "#aaa";
    ctx.beginPath();
    for(let i = 0; i < Math.max(imageSize.cm.height, imageSize.cm.width) * 5; i += 1) {
        if (i % 5) {
            ctx.rect(0, i * sy / 5 | 0, w, 1);
            ctx.rect(i * sx / 5 | 0, 0, 1, h);
        }
    }
    ctx.fill();
    ctx.fillStyle = "#000";
    ctx.beginPath();
    for(let i = 0; i < Math.max(imageSize.cm.height, imageSize.cm.width); i += 1) {
        ctx.rect(0, i * sy | 0, w, 1);
        ctx.rect(i * sx | 0, 0, 1, h);
    }    
    ctx.fill();
    ctx.globalAlpha = 1;
    ctx.font = "12px arial";
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillStyle = "#000";
    ctx.strokeStyle = "#FFF";
    ctx.lineWidth = 4;
    ctx.strokeText("cm", 12, 10);
    ctx.fillText("cm", 12, 10);
    for(let i = 1; i < Math.max(imageSize.cm.height, imageSize.cm.width); i += 1) {
        ctx.strokeText(i, 10, i * sy);
        ctx.strokeText(i, i * sx, 10);
        ctx.fillText(i, 10, i * sy);
        ctx.fillText(i, i * sx, 10);
    }
}
<canvas id="canvas"></canvas>

Примечание То, что физический и пиксельный размеры не совпадают, и, следовательно, масштаб холста растягивается в направлении y.

Чтобы получить квадратный аспект, вы должны использовать только одну шкалу для обоих значений x и y или изменить размер холста в соответствии с физическим аспектом.

...