Как нарисовать монохромное изображение на холсте, но использовать другой цвет? - PullRequest
1 голос
/ 24 сентября 2019

У меня есть черно-белое изображение.При необходимости я могу преобразовать его в прозрачный и белый.

Как я могу нарисовать это изображение на холсте, заменив белый произвольным цветом?

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

CPC 464 Font

Ответы [ 2 ]

2 голосов
/ 24 сентября 2019

Это можно сделать двумя способами.

За кадром

Создать закадровый холст, визуализировать текст на этом холсте и затем использовать ctx.globalCompositeOperation = "color"* 1007.* (обновить мой плохой, который должен быть ctx.globalCompositeOperation = "destination-in") сначала нарисуйте цвет, затем нарисуйте текст поверх цвета.(см. пример)

Пример вышеуказанного метода

canvas.width = 430;
canvas.height = 16;
const ctx = canvas.getContext("2d");

// off screen canvas
const text = document.createElement("canvas");
text.width = 512;
text.height = 16;
text.ctx = text.getContext("2d");

const font = new Image;
font.src = "https://i.stack.imgur.com/VXaVG.png"
font.addEventListener("load", () => {
    drawColorString("000Black text#F00 Red text#FF0 Yellow#0F0 Green#0FF Cyan#00F Blue#F0F Magenta", 10, 4);
});
const grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grad.addColorStop(0,"#FFF");
grad.addColorStop(1,"#000");
ctx.fillStyle = grad;
ctx.fillRect(0, 0, canvas.width, canvas.height);

function drawColorString(str, xpos, ypos) {
    const parts = str.split("#");
    var x = 0;
    for (const part of parts) {
        const color = part.slice(0,3);
        const chars = part.slice(3);
        for (const char of chars) {
            drawChar(char, color, x);
            x += 8;
        }
    }
    colorText();
    ctx.drawImage(text, xpos, ypos);
}
function colorText() {
    text.ctx.globalCompositeOperation = "destination-in";
    text.ctx.drawImage(text, 0, 8, text.width, 8, 0, 0, text.width, 8);
    text.ctx.globalCompositeOperation = "source-over";
}
function drawChar(char, color, xpos) {
    const c = char.charCodeAt(0);
    const x = (c % 32) * 8;
    const y = (c / 32 | 0) * 8;
    
    text.ctx.fillStyle = "#" + color;
    text.ctx.fillRect(xpos, 0, 8, 8);
    text.ctx.drawImage(font, x, y, 8, 8, xpos, 8, 8, 8);
 }
canvas {
    border:1px solid black;

}
<canvas id="canvas"></canvas>

Используется изображение шрифта

Example of masked font

Добавка

Второй способ - изменить исходное изображение, чтобы получить маскированную версию текста в черном, красном, зеленом, синем цветах.Чтобы отобразить цвет, нарисуйте черный текст, затем наложите, используя ctx.globalCompositeOperation = "lighter", чтобы добавить необходимые значения r, g, b.

Пример аддитивного метода

canvas.width = 430;
canvas.height = 16;
const ctx = canvas.getContext("2d");
const font = new Image;
font.src = "https://i.stack.imgur.com/FfGjd.png"
font.addEventListener("load", () => {

    drawColorString("000Black text#F00 Red text#FF0 Yellow#0F0 Green#0FF Cyan#00F Blue#F0F Magenta", 10, 4);
});
const grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
grad.addColorStop(0,"#FFF");
grad.addColorStop(1,"#000");
ctx.fillStyle = grad;
ctx.fillRect(0, 0, canvas.width, canvas.height);

function drawColorString(str, x, y) {
    const parts = str.split("#");
    for (const part of parts) {
        const color = part.slice(0,3);
        const chars = part.slice(3);
        for (const char of chars) {
            drawChar(char, color, x, y);
            x += 8;
        }
    }
}
function drawChar(char, color, xpos, ypos) {
    const addLayer = (channel, amount) => {
        if (amount) {
            ctx.globalAlpha = amount;
            ctx.drawImage(font, x, y + 64 * (channel + 1), 8, 8, xpos, ypos, 8, 8);
        }
    }
    const red   = parseInt(color[0] + color[0], 16) / 255; 
    const green = parseInt(color[1] + color[1], 16) / 255; 
    const blue  = parseInt(color[2] + color[2], 16) / 255; 
    const c = char.charCodeAt(0);
    const x = (c % 32) * 8;
    const y = (c / 32 | 0) * 8;
    ctx.globalAlpha = 1;
    ctx.drawImage(font, x, y, 8, 8, xpos, ypos, 8, 8);

    ctx.globalCompositeOperation = "lighter"; 
    addLayer(0, red);
    addLayer(1, green);
    addLayer(2, blue);
    
    ctx.globalCompositeOperation = "source-over"; // default
    ctx.globalAlpha = 1;
 }
canvas {
    border:1px solid black;

}
<canvas id="canvas"></canvas>

Пример изображения, использованного в приведенном выше фрагменте.

Example of RGB font

Или вы можете объединить два метода и использовать аддитивный метод для рендеринга цветного текста на экранном холсте, а затем нарисовать этот холст на холсте дисплея.Это означает, что вам нужно рисовать только текст, когда он изменяется, а не каждый кадр, если он анимирован.

2 голосов
/ 24 сентября 2019
  • Самый простой способ сделать это - заменить белый цвет на изображении прозрачной "дырой", в которой вы хотите получить цвет, а затем использовать .fillstyle, чтобы изменить фон холста.
  • Сохраните изображение в формате png, откройте некоторое программное обеспечение для редактирования фотографий и удалите отверстие в изображении, где вы хотите, чтобы цвет был таким, чтобы вы видели прозрачный клетчатый фон.
  • Переместите этот файл туда, куда вам нужносохраняйте изображения в своем проекте.
  • добавьте изображение к элементу холста, убедитесь, что оно заполняет весь холст.Используйте следующий код, чтобы изменить фон вашего холста:

let canvas = document.getElementByID("colourthis") let ctx = canvas.getContext("2D") ctx.fillstyle = 'red'

  • Прозрачные части изображения теперь будут красного цвета.
  • Вы можете использовать какой-то рандомизатор для получения других цветов.
  • используйте ctx.fillStyle = "transparent" для получения прозрачного фона.

Так я бы поступил в vanilla JS, нетJQuery или что-нибудь.Есть и другие способы, но, судя по тегам, которые вы использовали, я сомневаюсь, что вы используете какие-либо плагины для такого рода вещей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...