【问题标题】:HTML5 Canvas Image Draw with input text带有输入文本的 HTML5 画布图像绘制
【发布时间】:2015-08-26 03:09:45
【问题描述】:

我是 Canvas 的新手,我有一个任务,我有一个输入框来输入文本。然后我上传一张图片。当图片显示时,它应该在背景中重复文本。

到目前为止,我已经能够上传图像并对其进行轻微的灰度化,但我不知道如何使用文本在背景中重复

如果有人能指出下一步该做什么,那就太好了。-谢谢

到目前为止我的代码:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
<script>
document.addEventListener('DOMContentLoaded', function(){
    var canvas = document.getElementById('canvas');
    var context = canvas.getContext('2d');
    var source = document.getElementById('fileupload');
    source.addEventListener('change',handleImage,false);

    function handleImage(e){
        var reader = new FileReader();
        reader.onload = function(event){
            var img = new Image();
            img.onload = function(){

                context.drawImage(img,0,0);
                grayScale(context, canvas);
            }
            img.src = event.target.result;
        }
        reader.readAsDataURL(e.target.files[0]);
    }

    function grayScale(context, canvas) {
        var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
        var pixels  = imgData.data;
        for (var i = 0, n = pixels.length; i < n; i += 4) {
            pixels[i]+=20;
            var grayscale = (pixels[i*4] + pixels[i*4+1] + pixels[i*4+2]) /3;
            pixels[i*4  ] = grayscale;        // red
            pixels[i*4+1] = grayscale+30;        // green
            pixels[i*4+2] = grayscale;        // blue
           // pixels[i+3] = 0.5;            // is alpha
        }
        //redraw the image in black & white
        context.putImageData(imgData, 0, 0);
    }



})
</script>


        <input type="text" id="textcontent">
        <input type="range" id="slider">


        Background<input type="checkbox" id="background">
        Select file: <input id="fileupload" type="file" multiple>
        <canvas id='canvas' width="800" height ="800"></canvas>

</body>
</html>

【问题讨论】:

  • 您的屏幕截图中的文字似乎在背景中重复?背景是否需要某种颜色(例如白色)。创建图像后,可以在画布上重复文本,但困难的部分将决定背景与图像是什么。但取决于你如何定义,这不是什么大问题。
  • 如果选中背景颜色复选框,则背景为黑色,否则为白色。我想知道创建图像后如何在背景中重复文本。
  • 网上有很多这样的图像 --> ascii 生成器,其中许多都有所使用方法的描述。我已经好几年没有读到它们了。从记忆中,有几种方法似乎最常见 - 它们中的每一种都要求您可以检查用于最终图像的任何/所有字符的位图。一些简单地确定黑白像素的比率并使用它来计算字符的“亮度”,而另一些还考虑 哪里 找到像素,以提供形状匹配。考虑-_[:]&lt;:&gt;

标签: javascript html canvas html5-canvas


【解决方案1】:

我不确定这是否正是您想要的,但根据您给定的代码和您的要求,这是一个解决方案:

您可以先在新画布中draw your text,然后将其用作主画布的pattern。然后,由于 context2d 的 globalCompositeOperation 设置为 'destination-in',您可以只在图像上保留文本模式。

var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
var source = document.getElementById('fileupload');
source.addEventListener('change', handleImage, false);
var slider = document.getElementById('slider');
slider.onchange = handleImage;
var inputText = document.getElementById('textcontent');
inputText.onchange = handleImage;

function handleImage(e) {
  if (source.files.length < 1) return;
  var reader = new FileReader();
  reader.onload = function(event) {
    var img = new Image();
    img.onload = function() {
      context.fillRect(0, 0, canvas.width, canvas.height);
      context.drawImage(img, 0, 0);
      grayScale(context, canvas);
      textBackground();
    }
    img.src = event.target.result;
  }
  reader.readAsDataURL(source.files[0]);
}

function grayScale(context, canvas) {

  var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
  var pixels = imgData.data;
  for (var i = 0, n = pixels.length; i < n; i += 4) {
    pixels[i] += 20;
    var grayscale = (pixels[i] + pixels[i + 1] + pixels[i + 2]) / 3;
    pixels[i] = grayscale; // red
    pixels[i + 1] = grayscale + 5; // green
    pixels[i + 2] = grayscale; // blue
    // pixels[i+3] = 0.5;            // is alpha
  }
  //redraw the image in black & white
  context.putImageData(imgData, 0, 0);
}

function textBackground() {
  var txt = inputText.value;
  if (!txt) return;
  var fontSize = +slider.value;

  var c = document.createElement('canvas'),
    ctx = c.getContext('2d');

  var check = document.getElementById('background').checked;
  //set the fontSize so we are able to set our canvas size
  ctx.font = fontSize + "px Arial";
  c.width = ctx.measureText(txt).width + fontSize;
  c.height = fontSize;
  // set it again since the change of width has reset it
  ctx.font = fontSize + "px Arial";
  ctx.fillText(txt, 0, fontSize);
  // draw our text

  var pattern = context.createPattern(c, 'repeat');
  // set our main canvas fillStyle to our newly created pattern
  context.fillStyle = pattern;
  // should we keep only the text or draw the text over the image
  context.globalCompositeOperation = check ? 'destination-in' : 'source-over';
  context.fillRect(0, 0, canvas.width, canvas.height);
  // reset the context
  context.globalCompositeOperation = 'source-over';
  context.fillStyle = "#000";
}
<input type="text" id="textcontent">
<input type="range" id="slider" min=4 max=40 value=6>Background


<input type="checkbox" checked id="background">Select file:
<input id="fileupload" type="file" multiple>
<canvas id='canvas' width="800" height="800"></canvas>

注意:我还修复了您的灰度功能,以避免可能不需要的莫尔效应。

【讨论】:

  • 谢谢!这非常接近我想要的。不过只有一件事。当我在我的系统上运行它时,文本在水平方向上间隔很远,但垂直方向很好。我想知道为什么会这样。
  • 我的页面如上图所示。有什么建议吗?
  • 确实,这里似乎有一个错误。乍一看,我会说它与返回未定义的 ctx.meaureText 方法有关,但我认为 FF 家伙会发现这一点,所以它可能是(纯粹的猜测,我不记得 measureText 是如何处理这个的)你不'你的系统上没有字体。如果您想自己检查,请尝试将c 附加到文档并检查其宽度。如果看起来正确,那么问题来自 createPattern。无论如何,我明天会在我的 Ubuntu 上尝试。
  • 我想知道这是否是浏览器问题。似乎在 chrome 上工作正常。不在火狐上。
  • 看来我根本不应该使用它。任务是让一个带有文本的 div 作为多个跨度元素,并且图像应该在上面。这样如果我选择图像中的文本,它就可以被选中。我不知道该怎么做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-22
  • 2021-02-14
  • 2012-08-15
  • 2020-04-14
相关资源
最近更新 更多