python : https://github.com/paper/auto-css-sprite-python
地址: changelog.md
内有示例图片 和 一些改动说明
- 整体页面简约为主,温和的色调,长时间使用,眼睛也不会疲劳
- 左侧显示canvas图片和demo文本(会自适应),右侧是拖入图片区域,下面是一些操作按钮区域
- “反转canvas颜色” 按钮,是为了让用户看得清比较偏白的图标
- 拖一些图标进入“Drag img here” 区域时,底色会变,这时,你只要松手就可以了
- 系统会自动生成合并的图片,还有demo代码
- 由于浏览器限制,点击 “保存图片” 会新开窗口,然后在新开的窗口内,点击图片,会提示保存图片
- 右下角 “设置” ,可以设置 “class标识” 和 “sprite路径”,让你的class命名区别于其他
- class命名,采用 “acs” + “class标识” + “图片文件名” 。图片文件名任何不合法的字符都会被转化为 “-”。推荐“图片文件名”和“class标识”都是纯英文描述。比如:图片文件名 good.png、add.png 等等,class标识 一般是项目名称 projectName
主要参考 http://www.aaai.org/Papers/ICAPS/2003/ICAPS03-029.pdf 算法
- 排列矩形集合(S),按照高度从高到低进行排序
- 取最高的1个矩形(s1)的宽高作为容器(Box)的初始宽高(BoxW,BoxH)
- s1永远处于Box的左上角。BoxH 不变,BoxW 可以无线延伸
- 判断第2个矩形(s2)能不能放到 Box 按照从左到右,从高到底这个顺序的空隙里面
- 如果可以:放入 并 判断 BoxW 是否需要延伸
- 如果不可以:放到s1的右边,BoxW 延伸
- 继续第3步,判断s3, s4, s5......
- 根据Box的初始高度,可以得到最终最小面积(Nice)的第一个样本(Sample)
- 通过阶梯增加Box的高度(boxHeightStep),得到多个样本
- 比较每个样本的 面积利用率(U),取最高的那个
通过上面的描述,我们可以知道,算法的核心就是如何快速有效的判断 “Box 从左到右,从高到底这个顺序的空隙的坐标” 在哪?
我没有采用论文的切片算法(看得不是很懂),用的是自己研究的 “长条移动” 法。[ S里面最小高度是 MINH ]
- 假想有一个宽度为1px宽度,高度为BoxH 的长条(L),覆盖在Box左上角上面
- L 从左到右移动,x方向坐标(x),不断增加阶梯(xStep)
- 分析 L 和 已经放入到Box的矩形(InS) 相交
- 如果不相交,就把最新的s(sn) 放入到(x, 0)值的位置,更新 BoxW
- 如果相交
- 相交的矩形(xS)的高度总和(xSH)+ MINH >= H,说明不可能有位置放 sn 了,记录下当前x值(下次就不需要判断了),继续移动 L
- 如果 xSH + MINH < H,有空隙。分析 L 与 xS 形成的 “相交线段” 空隙数量 和 长度
- 如果所有空隙长度 分别小于 sn 高度(snH),继续移动 L
- 如果有个空隙长度 大于 snH,放入 sn 在 (x, y)[y 是指空隙的y值], 判断 sn 和 InS 有没有重叠,如果不重叠,放入。反之 继续移动 L
- 判断下一个 sn , 重复 1
// L 移动的步长
// 【测试说明】以下测试,都是没有开启这2个开发工具。开启 firebug 或 chrome开发者工具,会影响测试值
// 【测试环境】chrome35 和 firefox30,样本10个,boxHeightStep为16px
// 【测试数据】big-and-small里面79张图片,单位 ms (毫秒)
// xStep=1 chrome消耗的时间:1907, firefox消耗的时间:890, 最佳利用率:0.961
// xStep=2 chrome消耗的时间:893 , firefox消耗的时间:506, 最佳利用率:0.955
// xStep=4 chrome消耗的时间:517 , firefox消耗的时间:286, 最佳利用率:0.938
var xStep = 2;
这是个NP问题,所以只能求近似最佳值。 影响这个算法性能和精度的地方有:
- xStep的值
- boxHeightStep 的值
- Sample 个数
所以,如果你想要更高的精度(毕竟是本地程序,多等待那么几秒,问题不大)
请设置
xStep = 1; Sample >= 20; boxHeightStep <= 16
- 如何更加有效、智能的 设置 boxHeightStep 最佳值?
- Sample 多少个才合理?
- 有没有更好更快的算法?
写这个也是因为用过了cssgaga,一个很棒的工具!作者推荐大家 不要重复造轮子,只要会用这个工具就可以了。
看过文章和评论后,研究一下文章给出的 Optimal Rectangle Packing: Initial Results,单独提取 algo.js 核心算法 ,内有非常详细的注释。
我已经写了一个简单的python版本
大家可以随意改成 java ,php,c/c++ 等其他版本。 :D