【问题标题】:How to decide/check whether some point belongs to a vector shape or not?如何决定/检查某个点是否属于矢量形状?
【发布时间】:2012-09-13 21:52:56
【问题描述】:

我在 Photoshop 中创建了一些地图 (8000x8000)。地图的每一部分都是使用自定义形状工具创建的,并且可以导出为 *.ai 文件。所以我将一个示例形状导出到 *.ai 文件,该文件具有以下内容:

%!PS-Adobe-2.0
%%Creator: Adobe Photoshop(TM) Pen Path Export 7.0
%%Title: (map-small-paddington.ai)
%%DocumentNeededResources: procset Adobe_packedarray 2.0 0
%%+ procset Adobe_IllustratorA_AI3 1.0 1
%%ColorUsage: Black&White
%%BoundingBox: 0 0 7998 7998
%%HiResBoundingBox: 0 0 7998.9998 7998.9998
%AI3_Cropmarks: 0 0 7998.9998 7998.9998
%%DocumentPreview: None
%%EndComments
%%BeginProlog
%%IncludeResource: procset Adobe_packedarray 2.0 0
Adobe_packedarray /initialize get exec
%%IncludeResource: procset Adobe_IllustratorA_AI3 1.0 1
%%EndProlog
%%BeginSetup
Adobe_IllustratorA_AI3 /initialize get exec
n
%%EndSetup
0.0 0.0 0.0 1.0 k
0 i 0 J 0 j 1 w 4 M []0 d
%%Note:
%Adobe_Photoshop_Path_Begin:<< /defaultFill false >>
*u
%AI3_Note:<< /operation /union >>
0 XR
4771.1153 4121.9960 m
4855.5878 4111.9732 4957.9582 4086.2029 5003.7736 4060.4311 c
5049.5891 4034.6599 5120.0382 3972.7994 5193.7738 3957.0505 c
5267.5089 3941.3016 5323.5226 3946.6539 5355.9339 3949.0778 C
5356.7559 3955.9301 5358.4651 3964.2284 5361.9409 3972.1987 C
5361.4717 3972.3317 L
5358.0990 3975.3640 5353.5658 3979.5329 5347.8721 3984.9663 c
5333.9035 3998.3003 5250.7315 4090.9969 Y
5162.4795 4165.2807 5134.5423 4193.2165 v
5106.6045 4221.1528 5064.0674 4221.7889 5022.1634 4227.5026 c
4980.2590 4233.2172 4968.8311 4237.6617 4932.0072 4254.1706 c
4895.1828 4270.6786 4843.1201 4292.2642 4827.8818 4298.6139 c
4812.6435 4304.9637 4796.1361 4316.3911 4778.9935 4340.5184 c
4761.8505 4364.6433 4745.9776 4385.5963 4728.8351 4398.9284 c
4723.2744 4403.2528 4716.9076 4407.1833 4712.3291 4410.3572 C
4681.6484 4314.8482 4661.9599 4219.4050 V
4662.8157 4217.2633 4684.8314 4162.2146 4701.6759 4132.7359 C
4710.9826 4122.7135 4771.1153 4121.9960 Y
n
*U
%Adobe_Photoshop_Path_End
%%Trailer
%%EOF

现在假设我有两点:(4830,3780) 属于这个形状,(4480,3130) 不属于这个形状。我知道是因为我在 Photoshop 中检查过。

但我的问题是如何以编程方式检查我想要的每一点?有没有办法在 PHP 中做到这一点?

所以问题由两部分组成:

  1. 加载和读取 *.ai 文件
  2. 检查点是否属于形状。

任何帮助将不胜感激。

【问题讨论】:

  • 形状交叉点呢?有礼物吗?
  • 它可能会发生,但是点可以属于第一个或第二个区域 - 我不在乎。因此,如果我在一个区域找到这一点,我将不会在另一个区域中寻找它。

标签: php photoshop adobe-illustrator


【解决方案1】:

我能想到的检查内部/外部的最简单方法是光栅化图像并使用颜色。

创建一个地图版本,其中形状元素全为黑色,背景为白色。将其保存为 JPEG。如果您安装了带有 GD 或 Imagemagik 扩展的 PHP,PHP 可以在您想要的坐标处从图像中挑选颜色:

<?php
$im = imagecreatefromjpeg('map.jpg'); // Import black/white map image
var_dump(isInside($im, 4830, 3780)); // bool(true)
var_dump(isInside($im, 4480, 3130)); // bool(false)

function isInside($im, $x, $y) {
  $rgb = imagecolorat($im, $x, $y);
  $colors = imagecolorsforindex($im, $rgb);
  $value = ($colors['red'] + $colors['green'] + $colors['blue'])/3; // Get average value
  return ($value <= 10)? true : false; // If average value is less than 10, this pixel is black (or very close to it), so is inside a shape
}
?>

我在这里使用$value &lt;= 10 而不是$value == 0,因为在你的形状边缘,你会得到一点混叠,白色背景会融入黑色形状。颜色值是从 0 到 255,因此 10/255 仍然很黑,并且可以确保如果您针对靠近形状边界的像素,它仍然可以正确评估。

【讨论】:

  • 这是我从未想过的方式......谢谢 - 我会尝试你的解决方案并写下一些想法。
  • 也许我会把这个文件导出为png(透明背景上的黑色形状),这样就不会有抗锯齿问题。
  • @Carlos “透明”与“白色”作为背景没有区别;靠近形状边缘的一些像素不完全是“形状”颜色,也不完全是“背景”颜色,您必须决定在什么阈值处将它们切断。
  • 是的,这就是我选择透明的原因。当我把所有没有设置 alpha 的像素设置为 127 时。所以 alpha 126 对我来说仍然是一些颜色。使用这种方法,我不需要计算任何东西。我只是拿 alpha 并与我想要的比较。无论如何 - 正如你所说 - 这只是一个细节,没有任何区别。
  • 对; alpha &lt;= 126 实际上与 $value &lt;= 253 相同,因为我的脚本错误方式是在边缘抓取太多而不是太少。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 2020-05-21
  • 2012-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多