UI制作中的九宫格批量输出
2014-05-29 23:07
633 查看
游戏的UI制作中,出于对资源的压缩和重用,会对一些有规则的图片划分九宫格,例如下图
中间部分如果是纯色的话,完全可以挖去,然后在U3D的图集精灵的border中设置对应的top,right,bottom,left,这样既可以节省资源,又可以重用到不同大小的但具有一样颜色的地方。
传统的photoshop可以挖去中间部分,但是项目中的美术大哥觉得还是批量处理比较有效率,所以用Air写了一个批量处理九宫格图片的工具。
在这个工具中,美术需要把九宫格的四个border值填充到名字,顺序为top, right, bottom, left例如
top=20px, right=20px, bottom=20px, left=20px,那么图片的命名为Button#21#22#23#24.png
(Button#top#right#bottom#left.png)
这样多个图片导入工具中,导出来的效果
这样资源和可重用度都得到很好的提升。
工具是用air来做的,核心源码如下
原理是先把九宫格的九个小块的bitmapData记录到一个数组里面,然后根据划分的top,right,bottom,left的大小取出对应的bitmapData拼成新图。
特别地,如果是三宫格,如下图
所有引用这张精灵图的宽度都是原大小228px,固定不变的,不能拉伸水平方向,那么需要把left和right设为width的一半,垂直方向可以拉伸,还是20px。同理如果是垂直方向不能拉伸,固定不变,则top和bottom设为height的一半。
中间部分如果是纯色的话,完全可以挖去,然后在U3D的图集精灵的border中设置对应的top,right,bottom,left,这样既可以节省资源,又可以重用到不同大小的但具有一样颜色的地方。
传统的photoshop可以挖去中间部分,但是项目中的美术大哥觉得还是批量处理比较有效率,所以用Air写了一个批量处理九宫格图片的工具。
在这个工具中,美术需要把九宫格的四个border值填充到名字,顺序为top, right, bottom, left例如
top=20px, right=20px, bottom=20px, left=20px,那么图片的命名为Button#21#22#23#24.png
(Button#top#right#bottom#left.png)
这样多个图片导入工具中,导出来的效果
这样资源和可重用度都得到很好的提升。
工具是用air来做的,核心源码如下
private static var file:File = new File(); private var fileOutput:File = new File(); private static var fileStream:FileStream = new FileStream(); private var loader:Loader = new Loader(); private var bit:Bitmap = new Bitmap(); private var bytes:ByteArray = new ByteArray; private static const SLICE_LIST_LENGTH:int = 9; private static const SPLIT_ROW_COUNT:int = 3; private static const SPLIT_COL_COUNT:int = 3; private static var _transformMatrix:Matrix; private static var _splitRow:Vector.<int>; private static var _splitCol:Vector.<int>; private static var _rect:Rectangle; private static var _dstPoint:Point; private var m_iIndex:int = 0; private var m_arrFile:Array; private var fileAns:File; //mxml OnInit初始化函数 private function init():void { _splitRow = new Vector.<int>(SPLIT_ROW_COUNT + 1, true); _splitCol = new Vector.<int>(SPLIT_COL_COUNT + 1, true); _rect = new Rectangle(); _dstPoint = new Point(); _transformMatrix = new Matrix(); } //点击按钮后弹出文件夹选择对话框,目前只支持png文件 private function onImport(e:MouseEvent):void { file.addEventListener(FileListEvent.SELECT_MULTIPLE, this.onSelect); file.browseForOpenMultiple("请选择png文件(可选择多个)", [new FileFilter("png文件","*.png;")]); } //选择图片,可以多个以及输出文件夹 //文件的命名规范是 abc#top#right#bottom#left.png private function onSelect(e:FileListEvent):void { m_arrFile = e.files; fileOutput.addEventListener(Event.SELECT, this.OnDoIt); fileOutput.browserForDirectory("请 4000 选择输出的文件夹"); } //串行顺序处理图片 private function OnDoIt(e:Event):void { fileAns = e.target as File; m_iIndex = 0; DealFile(m_arrFile(m_iIndex)); } //读取图片,转成二进制 private function DealFile(file:File):void { var fileByte:ByteArray = new ByteArray(); var fs:FileStream = new FileStream(); fs.open(file, FileMode.READ); fs.readBytes(fileByte, 0, fs.bytesAvailable); fs.close(); var myLoader:Loader = new Loader(); myLoader.unload(); myLoader.loadBytes(fileByte); myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, image_completeHandler); } //把图片的二进制转成bitmapData private function image_completeHandler(event:Event):void { bit.bitmapData = Bitmap(event.currentTarget.content).bitmapData; Export(); } //把图片的中间部分挖空,导出图片 private function Export():void { var pngSource:BitmapData = new BitmapData(bit.width,bit.height,true,0); pngSource.draw(bit.bitmapData); var sName:String = m_arrFile[m_iIndex].name.replace(".png",""); trace(sName); var arrName:Array = sName.split("#"); //width = left + right; height = top + bottom; var ansPng:BitmapData = createScaleBitmapData(pngSource,int(arrName[2])+int(arrName[4]),int(arrName[1])+int(arrName[3]),int(arrName[1]),int(arrName[2]),int(arrName[3]),int(arrName[4])); //用到PNGEncoder库,把bitmapData转成二进制 var ba:ByteArray = PNGEncoder.encode(ansPng); //重命名,后面添加_Nine var ff:File = fileAns.resolvePath(m_arrFile[m_iIndex].name.replace(".png","_Nine.png")); //写入文件 var fileStream:FileStream = new FileStream(); fileStream.open(ff, FileMode.WRITE); fileStream.writeBytes(ba); fileStream.close(); //顺序执行后面的图片 if(++m_iIndex < m_arrFile.length) { DealFile(m_arrFile[m_iIndex]); } } private static function createScaleBitmapData(link:BitmapData, width:int, height:int, top:int, right:int, bottom:int, left:int):BitmapData { if(width < left + right) { width = left + right; } if(height < top + bottom) { height = top + bottom; } var result:BitmapData = new BitmapData(width, height, true, 0); //获取九宫格9个小块的BitmapData var gridList:Vector.<BitmapData> = createBitmapDataGridList(link, top, right, bottom, left); updateSplitData(width, height, top, right, bottom, left); for(var i:int = 0; i < SPLIT_COL_COUNT; i++) { for(var j:int = 0; j < SPLIT_ROW_COUNT; j++) { var grid:BitmapData = gridList[i * 3 + j]; if(_splitRow[j + 1] - _splitRow[j]==0 || _splitCol[i + 1] - _splitCol[i] == 0) { continue; } //把原点平移到对应slice的左上角 _transformMatrix.a = (_splitRow[j + 1] - splitRow[j]) / grid.width; _transformMatrix.b = 0; _transformMatrix.c = 0; _transformMatrix.d = (_splitCol[i + 1] - _splitCol[i]) / grid.height; _transformMatrix.tx = _splitRow[j]; _transformMatrix.ty = _splitCol[i]; result.draw(grid, _transformMatrix); } } return result; } //存储9个小图片的BitmapData private static function createBitmapDataGridList(link:BitmapData, top:int, right:int, bottom:int, left:int) : Vector.<BitmapData> { var source:BitmapData = link; if((top + bottom) > source.height || (left + right) > source.width) { throw new Error("图片九宫格参数设置错误:左右切片宽度之和不能大于图片宽度,上下切片高度之和不能大于图片高度!"); } var result:Vector.<BitmapData> = new Vector.<BitmapData>(SLICE_LIST_LENGTH, true); updateSplitData(source.width, source.height, top, right, bottom, left); for(var i:int = 0; i < SPLIT_COL_COUNT; i++) { for(var j:int = 0; j < SPLIT_ROW_COUNT; j++) { _rect.x = _splitRow[j]; _rect.y = _splitCol[i]; _rect.width = _splitRow[j+1] - _splitRow[j]; _rect.height = _splitCol[i+1] - _splitCol[i]; if(_rect.width == 0 || _rect.height == 0) { continue; } var bmpd:BitmapData = new BitmapData(_rect.width, _rect.height, true, 0); bmpd.copyPixels(source, _rect, _dstPoint); result[i * 3 + j] = bmpd; } } return result; } //划分9个小块的位置线 private static function updateSplitData(width:int, height:int, top:int, right:int, bottom:int, left:int):void { _splitRow[0] = 0; _splitRow[1] = left; _splitRow[2] = width - right; _splitRow[3] = width; _splitCol[0] = 0; _splitCol[1] = top; _splitCol[2] = height - bottom; _splitCol[3] = height; }
原理是先把九宫格的九个小块的bitmapData记录到一个数组里面,然后根据划分的top,right,bottom,left的大小取出对应的bitmapData拼成新图。
特别地,如果是三宫格,如下图
所有引用这张精灵图的宽度都是原大小228px,固定不变的,不能拉伸水平方向,那么需要把left和right设为width的一半,垂直方向可以拉伸,还是20px。同理如果是垂直方向不能拉伸,固定不变,则top和bottom设为height的一半。
相关文章推荐
- WebGame UI 制作之使用 对位图进行九切片(九宫格)缩放
- (转)在endnote中制作GB/T7714《文后参考文献著录规则》的输出格式
- wp7天气预报源代码(三UI的制作)下载地址更新
- 我的Unity(10)一点一滴 利用UI制作摇杆控制物体移动
- 用Fragment制作的Tab页面产生的UI重叠问题
- wp7天气预报源代码(三UI的制作)下载地址更新
- UI教你怎么制作PSD图
- EDIUS中的视频如何实现批量输出
- qt使用uic命令将后缀名为.ui的文件输出成.h文件方法
- LUA教程(游戏UI制作)二
- mongodb 批量查询 输出指定字段
- CryEngineV UI 制作
- 使用FlashCS制作UI导出swc在Actionscript中调用
- windows下批量读取文件夹及子文件夹下的文件名字,方便制作训练样本
- 利用脚本批量输出TexturePacker纹理
- 使用Qt Style Sheets制作UI特效
- Qt 批量操作 UI 控件
- Unity制作九宫格手机手势解锁密码
- UI -- 制作view渐变的效果CAGradientLayer
- iOS开发的UI制作中动态和静态单元格的基本使用教程