【问题标题】:outlining text in processing在处理中概述文本
【发布时间】:2018-05-22 06:15:25
【问题描述】:

我的目标是获得 1 像素宽的文本轮廓。

它可能看起来像这样:https://jsfiddle.net/Lk1ju9yw/

我想不出一个好的方法来解决这个问题,所以我做了以下(伪代码):

PImage img;

void setup() {
  size(400, 400);    
  // use text() to write on the canvas
  // initialize PImage img
  // load pixels for canvas and img
  // loop thru canvas pixels and look for contrast
  for (int x = 0; x < width; x++) {
    for (int y = 0; y < height; y++) {
      // compare canvas pixels at x-y with its neighbors
      // change respective pixel on PImage img so as not to disturb canvas
    }
  }
  // update pixels and draw img over the canvas
  img.updatePixels();
  img(img, 0, 0);
}

简而言之,我在画布上的黑色背景上写了白色文本,进行了一些边缘检测并将结果绘制在 PImage 上,然后使用 PImage 存储结果。我想我可以跳过 PImage 阶段,但我想看看边​​缘检测算法产生了什么。

所以这在获取大纲方面做得不错,但存在一些问题:

  1. 轮廓有时是 1+ 像素宽。这是个问题。假设我想将轮廓(即白色像素的所有位置)存储在 ArrayList 中。

例如,如果使用 ArrayList 我在轮廓的每个点上绘制一个椭圆,结果是可以的。但是如果我想让椭圆分开,椭圆轮廓会变得有点粗糙。在我提供的小提琴中,字母“h”的左边缘是 2 个像素宽。有时会在内部像素处绘制椭圆,有时在外部像素处绘制椭圆。那种东西让它看起来很丑。

  1. ArrayList 的元素可能是 ArrayList 中的邻居,但不是 PImage 中的邻居。如果我想为每 10 个 ArrayList 位置绘制一个圆圈,则结果不一定会在 PImage 上隔开。

这是一个丑陋的例子:https://jsfiddle.net/Lk1ju9yw/1/

我很确定我明白为什么会发生这种情况。我只是不知道如何避免它。

我也相信在 p5.js 中有一个解决方案(一种 PFont 方法)。我很喜欢使用 p5,但除非我必须(比如说,因为困难),否则我宁愿使用处理。我还听说过一些处理中的库可以帮助解决这个问题。部分原因是我对结果感兴趣,但我也有兴趣了解我是否可以自己编写解决方案(即在一些指导下)。

【问题讨论】:

    标签: processing processing.js


    【解决方案1】:

    您可以在 P5.js 中轻松获得文本轮廓,因为文本支持填充和描边颜色。所以如果你调用noFill(),文本将不会被填充,如果你调用stroke(0),文本将有一个黑色的轮廓。

    function setup() { 
      createCanvas(400, 200);
      noSmooth();
    } 
    
    function draw() { 
      background(220);
    	
      textSize(72);
      textAlign(CENTER);
    	
      noFill();
      stroke(0);
    	
      text("hey", width/2, height/2);
    }
    &lt;script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.16/p5.js"&gt;&lt;/script&gt;

    不幸的是,这种方法在常规处理中不起作用,因为它只使用文本的笔触颜色。我不太确定 Processing.js,但我猜它和 Processing 一样。

    如果将其绘制到缓冲区(使用createGraphics()),则可以遍历缓冲区以获取构成轮廓的点列表。

    现在,至于将分数按正确顺序排列,您将不得不自己做。我想到的第一种方法是对它们进行排序并按字母分组。

    例如,您的算法可能是:

    1. 找到最左上角的点。将其添加到您的列表中。
    2. 您刚刚添加的那个点有邻居吗?如果是这样,请选择一个并将其添加到您的列表中。重复此步骤,直到该点没有邻居。
    3. 还有积分吗?如果是这样,请找到最接近您刚刚添加的点,并将其添加到您的列表中。转到第 2 步。

    这可能并不完美,但如果您想要更高级的东西,您可能必须开始考虑处理点列表:例如,可能删除具有左邻居的点。您将不得不四处寻找您想要的效果。

    这是一个有趣的问题。谢谢。祝你好运,听起来是个有趣的项目。

    【讨论】:

      猜你喜欢
      • 2012-09-16
      • 2020-11-30
      • 1970-01-01
      • 2017-06-05
      • 1970-01-01
      • 2020-04-08
      • 1970-01-01
      • 1970-01-01
      • 2013-05-15
      相关资源
      最近更新 更多