如何消除生成的画布图像上的抗锯齿?

问题描述 投票:0回答:1

我正在开发一个项目,我需要将缩写放在另一张图像上,它可以工作,但有一个问题。

function downloadURI(uri, name) {
    const link = document.createElement('a');
    link.download = name;
    link.href = uri;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
}


function loadImage(url) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.crossOrigin = 'anonymous'; // Avoid CORS issues if needed
    img.onload = () => {
      resolve(img);
    };
    img.onerror = (err) => {
      console.error('Error loading image', err);
      reject(err);
    };
    img.src = url;
  });
}

async function createInitialsTextureWithImage(size = 2048, initials, imageUrl, color = [0, 0, 0]) {
  const textOffsetY = -64; 
  const textSize = 250; 

  try {
    await document.fonts.load(`normal ${textSize}px 'VCR OSD Mono'`);

    const canvas = document.createElement('canvas');
    canvas.width = size * 2; 
    canvas.height = size * 2; 
    const ctx = canvas.getContext('2d');

    const backgroundImage = await loadImage(imageUrl);

    ctx.clearRect(0, 0, size * 2, size * 2);
    ctx.drawImage(backgroundImage, 0, 0, size * 2, size * 2); 

    ctx.fillStyle = `rgb(${color[0]}, ${color[1]}, ${color[2]})`; 
    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    ctx.font = `${textSize * 2}px 'VCR OSD Mono'`; 
    ctx.fillText(initials, (size * 2) / 2, (size * 2) / 2 + textOffsetY * 2);

    const downscaledCanvas = document.createElement('canvas');
    downscaledCanvas.width = size;
    downscaledCanvas.height = size;
    const downscaledCtx = downscaledCanvas.getContext('2d');
    downscaledCtx.imageSmoothingEnabled = false;
    downscaledCtx.drawImage(canvas, 0, 0, size, size);

    return new Promise((resolve) => {
      downscaledCanvas.toBlob((blob) => {
        const file = new File([blob], 'initials.png', {
          type: 'image/png'
        });
        resolve(file); // Resolve with the file
      });
    });
  } catch (err) {
    console.error('Error in createInitialsTextureWithImage:', err);
    throw err;
  }
}

function displayGeneratedImage(file) {
  const imgElement = document.getElementById('generatedImage');
  const imageURL = URL.createObjectURL(file);
  downloadURI(imageURL, 'test.png'); // use to downloa it to local
  imgElement.src = imageURL;
}

document.getElementById('generateButton').addEventListener('click', async () => {
  try {
    const initials = 'NM';
    //const imageUrl = 'https://i.imgur.com/Gtwc8mZ.png'; 
    const imageUrl = 'https://i.imgur.com/V7K11Px.png';  
    const file = await createInitialsTextureWithImage(2048, initials, imageUrl, [0, 0, 0]);
    displayGeneratedImage(file);
  } catch (error) {
    console.error('Error generating image:', error);
  }
});
<link href="https://fonts.cdnfonts.com/css/vcr-osd-mono" rel="stylesheet">

<button id="generateButton">Generate</button>
<br><br>
<img id="generatedImage" alt="Generated Initials Texture" style="height: 500px; border: 1px solid #000;">

问题是,生成的图像添加了一些抗锯齿功能,并且字母包含一些灰色。

是否可以摆脱这种抗锯齿功能?

我已经尝试过:

  1. 缩放画布,
  2. imageSmoothingEnabled
    设置为
    false

但他们都没有帮助。

更新1:

我正在将此功能用于项目的另一部分:

combinedTextureUrl = await createInitialsTextureWithImage(2048, initials, textureLookup);
downloadURI(combinedTextureUrl, 'test.png');

发生这种情况是因为从生成的图像中可以看出,它就像:

![check

更新2:

由于某种原因,

downloadURI
不会在StackOverflow上触发,因此我创建了this fiddle,它将结果图像下载到本地,从而生成带有抗锯齿文本的结果。

javascript html
1个回答
0
投票

我已经找到了问题的解决方案。

我总是有一个具有 2-3 种颜色的图像,并且我知道缩写的颜色始终是黑色,因此我可以设置一个循环来检查每个像素并将其替换为黑色或白色。

    const imageData = rotatedCtx.getImageData(0, 0, size, size);
    const data = imageData.data;

    for (let i = 0; i < data.length; i += 4) {
        const r = data[i];
        const g = data[i + 1];
        const b = data[i + 2];

        const grayscale = 0.3 * r + 0.59 * g + 0.11 * b;

        const newColor = grayscale < 128 ? 0 : 255;
        data[i] = data[i + 1] = data[i + 2] = newColor;
    }

    rotatedCtx.putImageData(imageData, 0, 0);

通过这种方法,它用黑色代替了灰色边缘的颜色。

© www.soinside.com 2019 - 2024. All rights reserved.