200行代码实现马赛克拼图
2018-02-06 本文已影响23人
孙成酱子说
经常看到很多设计中用很多小图片拼接成一张大图,觉得很酷炫,给人的感觉也比较高大上,其实用代码实现也比较简单。
简单思路
将源图片分成很多小块,并忽略每一块的细节,得到一张马赛克图片并用二维数组记录每一块的色值。同样的对于拼接素材图片,先对素材图片进行裁剪,忽略每一张素材的细节,得到每一张素材的色值,用跟源图片快色值最近似的素材图片,逐一替换源图片中每一个块。
素材图片越多,效果越完美
原始图片
![](https://img.haomeiwen.com/i143039/022e05de559bf7c7.jpg)
将图片分成若干区域
![](https://img.haomeiwen.com/i143039/5fe277f50f6b9781.jpg)
将忽略图片区域细节(马赛克)
![](https://img.haomeiwen.com/i143039/86854619c4cff000.jpg)
拼接
![](https://img.haomeiwen.com/i143039/b66e20e25ac63b6d.jpg)
实践
代码地址
核心代码示例
def __get_tile_diff(self, t1, t2, bail_out_value):
diff = 0
for i in range(len(t1)):
# 计算两张图片的差异
diff += ((t1[i][0] - t2[i][0]) ** 2 + (t1[i][1] - t2[i][1]) ** 2 + (t1[i][2] - t2[i][2]) ** 2)
# 之前已经有更匹配的素材了,直接返回
if diff > bail_out_value:
return diff
return diff
def get_best_fit_tile(self, img_data):
best_fit_tile_index = None
# 值越大,差异越大
min_diff = sys.maxsize
tile_index = 0
# 遍历所有素材找到一个最匹配的素材图片
for tile_data in self.tiles_data:
diff = self.__get_tile_diff(img_data, tile_data, min_diff)
if diff < min_diff:
min_diff = diff
best_fit_tile_index = tile_index
tile_index += 1
return best_fit_tile_index