为了账号安全,请及时绑定邮箱和手机立即绑定

如何在图像中嵌入文本?

如何在图像中嵌入文本?

子衿沉夜 2022-09-29 16:58:26
我想在向用户显示该图像之前在图像中嵌入用户名。就像我有一个图像文件,现在我想把用户名放在图像里面,就像嵌入而不仅仅是放置文本一样。所以文字成为图像的实际部分?你们能不能建议我一个出路,输出schould是一个base64文件,这样我就可以通过api流式传输数据。谢谢。
查看完整描述

1 回答

?
手掌心

TA贡献1942条经验 获得超3个赞

您没有指定您的API服务器正在运行的软件,所以我为您的客户端水印需求编写了此内容。它仅适用于没有透明度的图像。

它是 LSB(最低有效位)编码的实现。

索引.html

<!DOCTYPE html>

<script src="index.js"></script>


<body>

</body>

<script>

  (async () => {

    const base64 = `data:image/png;base64,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`;

    const watermark = await createWatermark(base64, 'John Doe');


    const image = new Image();

    image.src = watermark;

    document.body.appendChild(image); // displays watermarked image on screen


    const hiddenText = await readWatermark(watermark, 8);

    console.log(hiddenText); // John Doe

  })();

</script>


</html>

索引.js


function stringToBits(string) {

  return string.split('')

    .map(char => char.charCodeAt(0))

    .map(int => (int).toString(2).padStart(8, '0').split(''))

    .flat()

    .map(n => +n);

}


function bitsToString(bits) {

  bits = [...bits.map(n => getBit(n, 0))];

  return String.fromCharCode(...Array(Math.ceil(bits.length / 8))

    .fill()

    .map(() => bits.splice(0, 8))

    .map(arr => parseInt(arr.join(''), 2)));

}


function setBit(number, bitPosition, sign) {

  if (sign) return number | (1 << bitPosition);

  const mask = ~(1 << bitPosition);

  return number & mask;

}



function getBit(number, bitPosition) {

  return (number & (1 << bitPosition)) === 0 ? 0 : 1;

}


function createWatermark(imageAsBase64, text) {

  return new Promise(resolve => {

    const image = new Image();

    image.src = imageAsBase64;

    image.onload = () => {

      const canvas = document.createElement('canvas');

      canvas.width = image.width;

      canvas.height = image.height;

      const context = canvas.getContext('2d');

      context.drawImage(image, 0, 0);

      const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

      const bits = stringToBits(text);

      for (let i = 0; i < text.length * 8; i += 4) {

        imageData.data[i] = setBit(imageData.data[i], 0, bits[i]);

        imageData.data[i + 1] = setBit(imageData.data[i + 1], 0, bits[i + 1]);

        imageData.data[i + 2] = setBit(imageData.data[i + 2], 0, bits[i + 2]);

        imageData.data[i + 3] = setBit(imageData.data[i + 3], 0, bits[i + 3]);

      }

      context.putImageData(imageData, 0, 0);

      resolve(canvas.toDataURL());

    }

  });

}


function readWatermark(base64, textLength) {

  return new Promise(resolve => {

    const image = new Image();

    image.src = base64;

    image.onload = () => {

      const canvas = document.createElement('canvas');

      canvas.width = image.width;

      canvas.height = image.height;

      const context = canvas.getContext('2d');

      context.drawImage(image, 0, 0);

      const imageData = context.getImageData(0, 0, canvas.width, canvas.height);

      const bits = imageData.data.slice(0, textLength * 8);

      resolve(bitsToString(bits));

    }

  });

}


查看完整回答
反对 回复 2022-09-29
  • 1 回答
  • 0 关注
  • 107 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信