像素精灵转直线多边形算法:突出像素顶点处理问询
问题描述
我正在编写一款可将任意像素精灵转换为直线多边形顶点集合的算法。该算法处理放大后的精灵时表现正常,但测试尺寸精确的精灵时,遇到了单个像素需对应两个相连顶点的边缘情况。我计划将生成的顶点集传入直线排序算法,以生成完整连通的折线。
边缘情况示例:突出像素
这类像素仅在一侧与其他像素相连,且两个对角方向的像素为非透明状态,例如俄罗斯方块的T型块:
+---+---+---+ | x | x | x | +---+---+---+ | x | x | x | +---+---+---+ | | x | | +---+---+---+ | | | | +---+---+---+
我该如何将此类像素转换为顶点?另外,如下十字形像素结构应如何表示为多边形?
+---+---+---+---+---+ | | | | | | +---+---+---+---+---+ | | | x | | | +---+---+---+---+---+ | | x | x | x | | +---+---+---+---+---+ | | | x | | | +---+---+---+---+---+ | | | | | | +---+---+---+---+---+
现有代码实现
顶点提取函数
def reduce_to_polygon(image): # 获取图像尺寸 width, height = image.size points = [] for y in range(height): for x in range(width): # 跳过透明像素 if image.getpixel((x, y))[3] == 0: continue if is_corner_pixel(image, x, y): points.append({'x': x, 'y': y}) return points
角像素判断函数
def is_corner_pixel(image, x, y): # 预先计算各方向邻居的透明状态 is_trans_top = image.getpixel((x, y-1))[3] == 0 if y > 0 else True is_trans_bottom = image.getpixel((x, y+1))[3] == 0 if y < image.height-1 else True is_trans_left = image.getpixel((x-1, y))[3] == 0 if x > 0 else True is_trans_right = image.getpixel((x+1, y))[3] == 0 if x < image.width-1 else True is_trans_top_left = image.getpixel((x-1, y-1))[3] == 0 if x > 0 and y > 0 else True is_trans_top_right = image.getpixel((x+1, y-1))[3] == 0 if x < image.width-1 and y > 0 else True is_trans_bottom_left = image.getpixel((x-1, y+1))[3] == 0 if x > 0 and y < image.height-1 else True is_trans_bottom_right = image.getpixel((x+1, y+1))[3] == 0 if x < image.width-1 and y < image.height-1 else True # 边缘情况:突出像素——仅单侧与其他像素相连,两个对角邻居非透明(如T型块) if (not is_trans_top_left and not is_trans_top and not is_trans_top_right and is_trans_right and is_trans_bottom_right and is_trans_bottom and is_trans_bottom_left and is_trans_left) \ or (not is_trans_top_right and not is_trans_right and not is_trans_bottom_right and is_trans_bottom and is_trans_bottom_left and is_trans_left and is_trans_top_left and is_trans_top) \ or (not is_trans_bottom_right and not is_trans_bottom and not is_trans_bottom_left and is_trans_left and is_trans_top_left and is_trans_top and is_trans_top_right and is_trans_right) \ or (not is_trans_bottom_left and not is_trans_left and not is_trans_top_left and is_trans_top and is_trans_top_right and is_trans_right and is_trans_bottom_right and is_trans_bottom): # TODO: 实现该情况的顶点生成逻辑 pass # 判断凸角像素:至少3个相邻邻居透明,且这些邻居彼此相邻,包含一个对角邻居 if (is_trans_left and is_trans_top_left and is_trans_top) \ or (is_trans_top and is_trans_top_right and is_trans_right) \ or (is_trans_right and is_trans_bottom_right and is_trans_bottom) \ or (is_trans_bottom and is_trans_bottom_left and is_trans_left): return True # 判断凹角像素:恰好一个对角邻居透明 if (is_trans_top_left and not is_trans_top and not is_trans_top_right and not is_trans_right and not is_trans_bottom_right and not is_trans_bottom and not is_trans_bottom_left and not is_trans_left) \ or (is_trans_top_right and not is_trans_right and not is_trans_bottom_right and not is_trans_bottom and not is_trans_bottom_left and not is_trans_left and not is_trans_top_left and not is_trans_top) \ or (is_trans_bottom_right and not is_trans_bottom and not is_trans_bottom_left and not is_trans_left and not is_trans_top_left and not is_trans_top and not is_trans_top_right and not is_trans_right) \ or (is_trans_bottom_left and not is_trans_left and not is_trans_top_left and not is_trans_top and not is_trans_top_right and not is_trans_right and not is_trans_bottom_right and not is_trans_bottom): return True return False
寻求解决方案
需要完善上述算法中突出像素的顶点转换逻辑,解决单个像素对应两个顶点的问题,同时处理十字形结构的多边形表示。
内容的提问来源于Stack Exchange,提问作者Saleh Bakra'a
相关产品推荐
相关产品推荐

