程序功能图标资源打包处理

PNG图标是个好东西,现在系统都支持而且工具软件都能很方便生成(包括PS),要比做Icon方便很多。因此理所当然的现在项目图标PNG已经霸占了ICON的霸主地位。

项目功能比较多的时候,就会有无数的图标资源。现做的项目功能图标单16x16规格已经有200个之多~~,一个功能一个PNG图标,散落在目录中(俺们的美工喜欢做PNG图标,不太喜欢做icon)。虽然有RC资源管理着,但程序第一次加载大量功能图标时,明显会感觉有些卡的感觉。实际性能测试中也确实反映出这个情况,加载功能图标耗时严重。

第一种:直接加入RC资源

一般处理功能图标的方法,把图标分组编号。如16x16规格的功能图标分成ACTION16的类型图标组,加载时枚举所有的Action16类型组资源名称,读入ImageList中。

处理过程:

1、枚举组资源名

2、加载PNG资源  x N次

3、转换成BMP带Alpha通道 x N次

4、装入ImageList x N次

1 ; 功能图标  16x16
2 ; ------------------------
3 ICON01  ACTION16 .\16\NewFile.png
4 ICON02  ACTION16 .\16\SaveFile.png
5 ... ...
6 ICONxx  ACTION16 .\16\xx.png

这种方式在资源比较少的时候没什么大问题,但资源一多时损失的效率就显现出来。

第二种:把一组资源拼接成单个文件

这种方式的好处显而易见,不需要枚举名称,只有一次读资源的过程,读出来的图标直接装入ImageList,由ImageList自动切割成16规格的图标。这效率是杠杠的~。

不过这种方式还是有个制作问题。这么多资源图标通常不是一次全部完成的,除了些基本的,其他的都是有了功能才有图标。功能图标样式修改,都要重新拼接。这个人力成本很大,再说了让俺们的美工MM做这事于心不忍啊。

解决方案

介于上面这两种情况,第一种效率慢、第二种费时费力。为解决问题本人又比较懒,所以想方法就是做个预处理。结合第一种RC管理的方法是用程序自动拼接,生成单个图标组资源文件。

如上面的16x16图标的RC内容独立出来一个配置文件(icons16.lst),维护图标的资源索引(程序内部有常量对应)。

1 ; icons16.lst
2 ;
3 ; 功能图标  16x16
4 ; ------------------------
5 .\16\NewFile.png
6 .\16\SaveFile.png
7 ... ...
8 .\16\xx.png

然后通过程序读取这个列表,合并图标资源并产生相应的常量定义代码。这事太美了,一箭双雕!哈~哈~哈~哈~~~

解决:资源加载慢,人工合并费时费力还不用手工维护代码常量表。

处理方案过程

1、读取定义列表

2、根据图标数量生成合并后的资源图标尺寸

3、依次读入,绘制到相应偏移位置。

4、压缩合并的资源图片并保存

OK~ 完成

 1 procedure TMergeSrv.Exec;
 2 var
 3   cConvert: TConvertRes;
 4 begin
 5   if FDataFile.ReadFileName then
 6   begin
 7     case FDataFile.Kind of
 8       dtIconMerge : cConvert := TMergeIcons.Create(FDataFile);
 9       dtPngPack   : cConvert := TPngPack.Create(FDataFile);
10       else          cConvert := nil;
11     end;
12
13     if cConvert <> nil then
14     begin
15       try
16         if cConvert.Exec(PrintMsg) then
17           if SaveResMap(cConvert.FIconMap) then
18             PrintMsg(format(‘Finish: %s‘,[ChangeFileExt(FDataFile.OutFileName, ‘.IconPack‘)]));
19       finally
20         cConvert.Free;
21       end;
22     end
23     else
24       PrintMsg(‘Err: ‘ + MSG_NONAMES);
25   end
26   else
27     PrintHelp;
28 end;

执行合并资源图标过程

1、读取参数定义列表

使用那个图标组索引定义,输出到哪里。主要有一个2个比较细节的地方。第一个:输出路径需要转换成完整路径(如: .\action16.pack)。第二个资源定义文件位置需要设成当前路径。这两个处理主要是为了简化PNG图标文件的读取。

 1 function TParams.ReadFileName: Boolean;
 2 var
 3   sFileName: string;
 4   sPath: string;
 5 begin
 6   Result := False;
 7   FileName := ‘‘;
 8
 9   // 从参数读取资源图标维护列表
10   sFileName := ChangeFileExt(ParamStr(0), ‘.lst‘);
11   if ParamCount >= 1 then
12     sFileName := Trim(ParamStr(1));
13   if FileExists(sFileName) then
14     FileName := sFileName;
15
16   // 从第二个参数中读取需要输出的资源包名称
17   // 情景:1、没有第二个参数,默认使用配置文件名
18   //       2、第二个参数是个路径,作为输出路径,文件名同配置名。
19   //       3、有明确输出文件名,直接使用。
20   OutFileName := ChangeFileExt(FileName, ‘.bmp‘);
21   if ParamCount >= 2 then
22   begin
23     sFileName := Trim(ParamStr(2));
24     if (sFileName <> ‘‘) then
25     begin
26       if (sFileName[Length(sFileName)] = ‘\‘) then
27         OutFileName := Format(‘%s%s‘,[sFileName, ExtractFileName(OutFileName)])
28       else
29       begin
30         OutFileName := sFileName;
31         if not DirectoryExists(ExtractFilePath(sFileName)) then
32           if not CreateDir(ExtractFilePath(sFileName)) then
33             OutFileName := ‘‘;
34       end;
35     end;
36   end;
37
38   // 把输出文件变成完整路径,为简化后续PNG资源的加载
39   if OutFileName <> ‘‘ then
40     OutFileName := ExpandFileName(OutFileName);
41
42   /// 设置当前处理目录,为简化后续图标资源的加载
43   if FileName <> ‘‘ then
44   begin
45     sPath := ExtractFilePath(FileName);
46     SetCurrentDir(sPath);
47     FileName := ExtractFileName(FileName);
48   end;
49
50   //
51   if SameText(ExtractFileExt(FileName), ‘.lst‘) then
52     Kind := dtIconMerge
53   else
54     Kind := dtPngPack;
55
56   Result := (FileName <> ‘‘) and (OutFileName <> ‘‘);
57 end;

读入参数设置的配置文件

 1 function TMergeIcons.LoadImageNames: Boolean;
 2 var
 3   I: Integer;
 4   sVal: string;
 5 begin
 6   // 读取配置文件
 7   //   清除空白行和注释行
 8   FFiles := TStringList.Create;
 9   FFiles.LoadFromFile(SourceFile);
10   for I := FFiles.Count - 1 downto 0 do
11   begin
12     sVal := Trim(FFiles[i]);
13     if (sVal = ‘‘) or (sVal[1] = ‘;‘) or (sVal[1] = ‘/‘) then
14       FFiles.Delete(i)
15     else
16       FFiles[i] := sVal;
17   end;
18
19   Result := FFiles.Count > 0;
20 end;

2、生成拼接图片的规格

 1 procedure TMergeIcons.BuildResMap;
 2 var
 3   bExists: Boolean;
 4   I: Integer;
 5 begin
 6   // 预读图标文件尺寸
 7   FIcon := TPngImage.Create;
 8   bExists := False;
 9   for I := 0 to Count - 1 do
10   begin
11     bExists := LoadIcon(0);
12     if bExists then
13       Break;
14   end;
15
16   if not bExists then
17     Exit;
18
19   // 设置图标拼接行列数
20   FColCnt := 10;
21   FRowCnt := Count div FColCnt;
22   if Count mod FColCnt > 0 then
23     inc(FRowCnt);
24
25   FWidth := FIcon.Width;
26   FHeight:= FIcon.Height;
27
28   BuildMap(FWidth * FColCnt, FHeight * FRowCnt);
29 end;

 1 procedure TConvertRes.BuildMap(w, h:Integer);
 2 begin
 3   FIconMap := TBitmap.Create;
 4   FIconMap.PixelFormat := pf32bit;
 5   FIconMap.alphaFormat := afIgnored;
 6   FIconMap.SetSize(w, h);
 7   // Alpha 透明化
 8   FIconMap.Canvas.Brush.Color := clBlack;
 9   FIconMap.Canvas.FillRect(Rect(0, 0, FIconMap.Width, FIconMap.Height));
10 end;

生成带有Alpha通道的透明Bitmap

3、并入资源图标

 1  for I := 0 to Count - 1 do
 2  begin
 3    if LoadIcon(i) then
 4    begin
 5      MergeIcon(i);
 6      PrintMsg(format(‘ok:并入资源(%d)%s‘, [i, FileNames[i]]));
 7    end
 8    else
 9      PrintMsg(format(‘Err: 无法加载 (%d)%s 文件‘, [i, FileNames[i]]));
10  end;

 1 function TMergeIcons.LoadIcon(AIndex: Integer): Boolean;
 2 begin
 3   try
 4     Result := False;
 5     if FileExists(FileNames[AIndex]) then
 6     begin
 7       FIcon.LoadFromFile(FileNames[AIndex]);
 8       Result := not FIcon.Empty;
 9     end;
10   except
11     Result := False;
12   end;
13 end;

fun LoadIcon

 1 function TMergeIcons.MergeIcon(AIndex: Integer): Boolean;
 2 var
 3   iCol: Integer;
 4   iRow: Integer;
 5 begin
 6   Result := True;
 7   // 按照索引进行偏移并入
 8   iRow := AIndex div FColCnt;
 9   iCol := AIndex mod FColCnt;
10   FIconMap.Canvas.Draw(FWidth * iCol, FHeight * iRow, FIcon);
11 end;

fun MergeIcon 根据索引进行偏移并入

4、压缩资源并输出

 1 function TMergeSrv.SaveResMap(ASource: TBitmap): Boolean;
 2 var
 3   cData: TMemoryStream;
 4   cPack: TZCompressionStream;
 5 begin
 6   Result := False;
 7   if ASource = nil then
 8     Exit;
 9   if not DirectoryExists(ExtractFilePath(FDataFile.OutFileName)) then
10     if not CreateDir(ExtractFilePath(FDataFile.OutFileName)) then
11       Exit;
12
13   // 把资源压缩到内存流中
14   cData := TMemoryStream.Create;
15   try
16     // 生成一份对照Bitmap文件,用户检测合并文件是否有问题。
17     ASource.SaveToStream(cData);
18     cData.SaveToFile(FDataFile.OutFileName);
19     cData.Clear;
20
21     // 生成资源使用的压缩包文件
22     cPack := TZCompressionStream.Create(clMax, cData);
23     try
24       ASource.SaveToStream(cPack);
25     finally
26       cPack.free;
27     end;
28     cData.SaveToFile(ChangeFileExt(FDataFile.OutFileName, ‘.IconPack‘));
29
30   finally
31     cData.Free;
32   end;
33   Result := True;
34 end;

最终产生的效果

下面是个测试目录,16文件夹是存放所有16x16规格的图标。Icons16.ist文件用于维护功能图标组文件。

执行完处理产生的合并文件

完成的目标文件

最终资源文件会产生一个具有Alpha通道的Bitmap文件,Alpha通道就是一个Mark文件。程序中产生同Icon相应的透明效果。

加载资源时不需要任何处理,直接加入到ImageList。完美解决主程序的加载资源消耗时间过长问题。

还种更懒的方法,列表配置文件都不需要,直接读取目录内所有文件进行拼接。这种方式只要在开发时约定图标资源的使用方式就没问题。如按照 前缀_<文件名> 方式引用。不管代码还是外部配置,代码就是定义的常量,外部配置就是个字符串,加载时转换到常量定义值。这样内部资源顺序不管怎么变都使用都不会受影响。

开发环境

XE3

Win7

完整单元代码

  1 program MergeRes;
  2
  3
  4 {$APPTYPE CONSOLE}
  5
  6 {$R *.res}
  7
  8 uses
  9   Winapi.Windows,
 10   Classes,
 11   Vcl.Graphics,
 12   System.SysUtils,
 13   Vcl.Imaging.pngimage,
 14   ZLib;
 15
 16 const
 17   MSG_NONAMES = ‘没有资源图标文件名称列表‘;
 18
 19 type
 20   TPrintProc = procedure (const AVal: string) of object;
 21
 22   TDataType = (dtIconMerge, dtPngPack);
 23
 24   TParams = class
 25   private
 26     FileName: string;
 27     OutFileName: string;
 28     Kind: TDataType;
 29
 30     function ReadFileName: Boolean;
 31   end;
 32
 33   TConvertRes = class
 34   private
 35     FParams: TParams;
 36     FIconMap: TBitmap;
 37     function GetSourceFile: string;
 38     procedure BuildMap(w, h:Integer);
 39   public
 40     destructor Destroy; override;
 41     constructor Create(AFiles: TParams); virtual;
 42
 43     function Exec(PrintMsg: TPrintProc): Boolean; virtual; abstract;
 44
 45     property SourceFile: string read GetSourceFile;
 46     property ResMap: TBitmap read FIconMap;
 47   end;
 48
 49   TPngPack = class(TConvertRes)
 50   public
 51     function Exec(PrintMsg: TPrintProc): Boolean; override;
 52   end;
 53
 54   TMergeIcons = class(TConvertRes)
 55   private
 56     FIcon: TPngImage;
 57     FRowCnt: Integer;
 58     FColCnt: Integer;
 59     FFiles: TStringList;
 60     FWidth: integer;
 61     FHeight: integer;
 62
 63     procedure BuildResMap;
 64     function GetCount: Integer;
 65     function GetFileNames(Index: Integer): string;
 66     function LoadIcon(AIndex: Integer): Boolean;
 67     function LoadImageNames: Boolean;
 68     function MergeIcon(AIndex: Integer): Boolean;
 69   public
 70     destructor Destroy; override;
 71     property Count: Integer read GetCount;
 72     property FileNames[Index: Integer]: string read GetFileNames;
 73
 74     function Exec(PrintMsg: TPrintProc): Boolean; override;
 75   end;
 76
 77   TMergeSrv = class
 78   private
 79     FDataFile: TParams;
 80     procedure PrintHelp;
 81     procedure PrintMsg(const AVal: string);
 82     function  SaveResMap(ASource: TBitmap): Boolean;
 83   public
 84     constructor Create;
 85     destructor Destroy; override;
 86
 87     procedure Exec;
 88   end;
 89
 90 constructor TMergeSrv.Create;
 91 begin
 92   FDataFile := TParams.Create;
 93 end;
 94
 95 destructor TMergeSrv.Destroy;
 96 begin
 97   FDataFile.free;
 98   inherited;
 99 end;
100
101 procedure TMergeSrv.Exec;
102 var
103   cConvert: TConvertRes;
104 begin
105   if FDataFile.ReadFileName then
106   begin
107     case FDataFile.Kind of
108       dtIconMerge : cConvert := TMergeIcons.Create(FDataFile);
109       dtPngPack   : cConvert := TPngPack.Create(FDataFile);
110       else          cConvert := nil;
111     end;
112
113     if cConvert <> nil then
114     begin
115       try
116         if cConvert.Exec(PrintMsg) then
117           if SaveResMap(cConvert.FIconMap) then
118             PrintMsg(format(‘Finish: %s‘,[ChangeFileExt(FDataFile.OutFileName, ‘.IconPack‘)]));
119       finally
120         cConvert.Free;
121       end;
122     end
123     else
124       PrintMsg(‘Err: ‘ + MSG_NONAMES);
125   end
126   else
127     PrintHelp;
128 end;
129
130 procedure TMergeSrv.PrintHelp;
131 begin
132   // TODO -cMM: TMergeSrv.PrintHelp default body inserted
133 end;
134
135 procedure TMergeSrv.PrintMsg(const AVal: string);
136 begin
137   Writeln(AVal);
138 end;
139
140 function TMergeSrv.SaveResMap(ASource: TBitmap): Boolean;
141 var
142   cData: TMemoryStream;
143   cPack: TZCompressionStream;
144 begin
145   Result := False;
146   if ASource = nil then
147     Exit;
148   if not DirectoryExists(ExtractFilePath(FDataFile.OutFileName)) then
149     if not CreateDir(ExtractFilePath(FDataFile.OutFileName)) then
150       Exit;
151
152   // 把资源压缩到内存流中
153   cData := TMemoryStream.Create;
154   try
155     // 生成一份对照Bitmap文件,用户检测合并文件是否有问题。
156     ASource.SaveToStream(cData);
157     cData.SaveToFile(FDataFile.OutFileName);
158     cData.Clear;
159
160     // 生成资源使用的压缩包文件
161     cPack := TZCompressionStream.Create(clMax, cData);
162     try
163       ASource.SaveToStream(cPack);
164     finally
165       cPack.free;
166     end;
167     cData.SaveToFile(ChangeFileExt(FDataFile.OutFileName, ‘.IconPack‘));
168
169   finally
170     cData.Free;
171   end;
172   Result := True;
173 end;
174
175 function TParams.ReadFileName: Boolean;
176 var
177   sFileName: string;
178   sPath: string;
179 begin
180   Result := False;
181   FileName := ‘‘;
182
183   // 从参数读取资源图标维护列表
184   sFileName := ChangeFileExt(ParamStr(0), ‘.lst‘);
185   if ParamCount >= 1 then
186     sFileName := Trim(ParamStr(1));
187   if FileExists(sFileName) then
188     FileName := sFileName;
189
190   // 从第二个参数中读取需要输出的资源包名称
191   // 情景:1、没有第二个参数,默认使用配置文件名
192   //       2、第二个参数是个路径,作为输出路径,文件名同配置名。
193   //       3、有明确输出文件名,直接使用。
194   OutFileName := ChangeFileExt(FileName, ‘.bmp‘);
195   if ParamCount >= 2 then
196   begin
197     sFileName := Trim(ParamStr(2));
198     if (sFileName <> ‘‘) then
199     begin
200       if (sFileName[Length(sFileName)] = ‘\‘) then
201         OutFileName := Format(‘%s%s‘,[sFileName, ExtractFileName(OutFileName)])
202       else
203       begin
204         OutFileName := sFileName;
205         if not DirectoryExists(ExtractFilePath(sFileName)) then
206           if not CreateDir(ExtractFilePath(sFileName)) then
207             OutFileName := ‘‘;
208       end;
209     end;
210   end;
211
212   // 把输出文件变成完整路径,为简化后续PNG资源的加载
213   if OutFileName <> ‘‘ then
214     OutFileName := ExpandFileName(OutFileName);
215
216   /// 设置当前处理目录,为简化后续图标资源的加载
217   if FileName <> ‘‘ then
218   begin
219     sPath := ExtractFilePath(FileName);
220     SetCurrentDir(sPath);
221     FileName := ExtractFileName(FileName);
222   end;
223
224   //
225   if SameText(ExtractFileExt(FileName), ‘.lst‘) then
226     Kind := dtIconMerge
227   else
228     Kind := dtPngPack;
229
230   Result := (FileName <> ‘‘) and (OutFileName <> ‘‘);
231 end;
232
233 procedure TMergeIcons.BuildResMap;
234 var
235   bExists: Boolean;
236   I: Integer;
237 begin
238   // 预读图标文件尺寸
239   FIcon := TPngImage.Create;
240   bExists := False;
241   for I := 0 to Count - 1 do
242   begin
243     bExists := LoadIcon(0);
244     if bExists then
245       Break;
246   end;
247
248   if not bExists then
249     Exit;
250
251   // 设置图标拼接行列数
252   FColCnt := 10;
253   FRowCnt := Count div FColCnt;
254   if Count mod FColCnt > 0 then
255     inc(FRowCnt);
256
257   FWidth := FIcon.Width;
258   FHeight:= FIcon.Height;
259
260   BuildMap(FWidth * FColCnt, FHeight * FRowCnt);
261 end;
262
263 destructor TMergeIcons.Destroy;
264 begin
265   if FFiles <> nil then FFiles.Free;
266   if FIcon <> nil then  FIcon.free;
267   inherited;
268 end;
269
270 function TMergeIcons.Exec(PrintMsg: TPrintProc): Boolean;
271 var
272   I: Integer;
273 begin
274   Result := False;
275   if LoadImageNames then
276   begin
277     BuildResMap;
278
279     for I := 0 to Count - 1 do
280     begin
281       if LoadIcon(i) then
282       begin
283         MergeIcon(i);
284         PrintMsg(format(‘ok:并入资源(%d)%s‘, [i, FileNames[i]]));
285       end
286       else
287         PrintMsg(format(‘Err: 无法加载 (%d)%s 文件‘, [i, FileNames[i]]));
288     end;
289
290     Result := True;
291   end
292   else
293     PrintMsg(‘Err: ‘ + MSG_NONAMES);
294 end;
295
296 function TMergeIcons.GetCount: Integer;
297 begin
298   Result := FFiles.Count;
299 end;
300
301 function TMergeIcons.GetFileNames(Index: Integer): string;
302 begin
303   Result := FFiles[Index];
304 end;
305
306 function TMergeIcons.LoadIcon(AIndex: Integer): Boolean;
307 begin
308   try
309     Result := False;
310     if FileExists(FileNames[AIndex]) then
311     begin
312       FIcon.LoadFromFile(FileNames[AIndex]);
313       Result := not FIcon.Empty;
314     end;
315   except
316     Result := False;
317   end;
318 end;
319
320 function TMergeIcons.LoadImageNames: Boolean;
321 var
322   I: Integer;
323   sVal: string;
324 begin
325   FFiles := TStringList.Create;
326   FFiles.LoadFromFile(SourceFile);
327   for I := FFiles.Count - 1 downto 0 do
328   begin
329     sVal := Trim(FFiles[i]);
330     if (sVal = ‘‘) or (sVal[1] = ‘;‘) or (sVal[1] = ‘/‘) then
331       FFiles.Delete(i)
332     else
333       FFiles[i] := sVal;
334   end;
335
336   Result := FFiles.Count > 0;
337 end;
338
339 function TMergeIcons.MergeIcon(AIndex: Integer): Boolean;
340 var
341   iCol: Integer;
342   iRow: Integer;
343 begin
344   Result := True;
345   // 按照索引进行偏移并入
346   iRow := AIndex div FColCnt;
347   iCol := AIndex mod FColCnt;
348   FIconMap.Canvas.Draw(FWidth * iCol, FHeight * iRow, FIcon);
349 end;
350
351 var
352   cSrv: TMergeSrv;
353
354 { TPngPack }
355
356 function TPngPack.Exec(PrintMsg: TPrintProc): Boolean;
357 var
358   cSrc: TPngImage;
359 begin
360   Result := False;
361   cSrc := TPngImage.Create;
362   try
363     cSrc.LoadFromFile(SourceFile);
364     if not cSrc.Empty then
365     begin
366       BuildMap(cSrc.Width, cSrc.Height);
367       ResMap.Canvas.Draw(0, 0, cSrc);
368       Result := True;
369     end;
370   finally
371     cSrc.Free
372   end;
373 end;
374
375 { TConvertRes }
376
377 procedure TConvertRes.BuildMap(w, h:Integer);
378 begin
379   FIconMap := TBitmap.Create;
380   FIconMap.PixelFormat := pf32bit;
381   FIconMap.alphaFormat := afIgnored;
382   FIconMap.SetSize(w, h);
383   // Alpha 透明化
384   FIconMap.Canvas.Brush.Color := clBlack;
385   FIconMap.Canvas.FillRect(Rect(0, 0, FIconMap.Width, FIconMap.Height));
386 end;
387
388 constructor TConvertRes.Create(AFiles: TParams);
389 begin
390   FParams := AFiles;
391 end;
392
393 destructor TConvertRes.Destroy;
394 begin
395   if FIconMap <> nil then
396     FIconMap.Free;
397   inherited;
398 end;
399
400 function TConvertRes.GetSourceFile: string;
401 begin
402   Result := FParams.FileName;
403 end;
404
405 begin
406   ReportMemoryLeaksOnShutdown := True;
407   cSrv := TMergeSrv.Create;
408   try
409     cSrv.Exec;
410   finally
411     cSrv.Free;
412   end;
413 end.

program MergeRes;

完整工程代码

https://github.com/cmacro/simple/tree/master/MergeIconsRes

时间: 2024-10-13 09:06:37

程序功能图标资源打包处理的相关文章

Windows下为go程序加入图标资源

a. 准备图标资源如demo.ico,适用WindowsXP的图标可以选择32x32或48x48. b.建立rc文件,如demo.rc 内容如下   IDI_ICON1 ICON "demo.ico" c.使用windres编译demo.rc.(windres.exe可以在MinGW中找到)  windres -o demo_res.syso demo.rc d.使用go工具编译即可 go build e.如果是多平台开发,非Windows平台不需要rc资源,可以建立以下批处理 bui

将资源打包到程序中

使用vs开发qt程序有时候不希望程序使用到的图片资源让用户看到,这时可以讲资源打包到程序中. 创建qrc资源文件,里面写入你使用到的图片资源路径,下面的代码中img是文件夹 <RCC> <qresource prefix="/" > <file>img/ball.png</file> <file>img/chinapool.jpg</file> <file>img/Globe.ico</file&

Unity资源打包之Assetbundle

转  Unity资源打包之Assetbundle 本文原创版权归 csdn janeky 所有,转载请详细注明原创作者及出处,以示尊重! 作者:janeky 原文:http://blog.csdn.net/janeky/article/details/17652021 如果这篇文章对你有帮助,敬请关注作者<Unity手游之路>系列教程. 在手游的运营过程中,更新资源是比不可少的.资源管理第一步是资源打包.传统的打包可以将所有物件制成预设Prefab,打包成场景.今天我们来一起学习官方推荐的As

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数

32位汇编第二讲,编写窗口程序,加载资源,响应消息,以及调用C库函数 (如果想看所有代码,请下载课堂资料,里面有所有代码,这里会讲解怎么生成一个窗口程序) 一丶32位汇编编写Windows窗口程序 首先我们知道32位汇编是可以调用Windows API的,那么今天我们就调用windowsAPI来写一个窗口程序 如果你有windows开发知识,那么就很理解了,如果没有,那么跟着我写,跟着步骤去写,那么也可以写出来 首先我们要编写一个窗口程序(使用SDKAPI编写)有几个步骤 1.设计窗口类 2.注

六: Windows应用程序开发界面资源

资源在应用程序开发中具有重要的作用.尤其是将界面元素(菜单.图标.位图等)作为资源,对降低程序设计的工作量大有帮助. 资源脚本(. rc) 资源是在资源脚本(. rc)中进行配置的.例如,把资源名字起为Window,再对Window进行如下配置, 1 添加资源 通过添加资源窗口,可以向.rc文件中添加需要的资源,比如常用的Dialog,Bitmap,Menu等. 添加完相应的资源后,Window.rc 文件内容如下: 2 绘制资源 这部不需要写代码,智能的Visual Studio允许使用"所见

如何将Debug文件夹下的资源打包成一个EXE文件直接执行

如何将Debug文件夹下的资源打包成一个EXE文件直接执行 前言:前段时间写了个小程序,想分享给好友看看,可所以资源都放在Debug文件夹下,整个文件夹发给人家这也太……,为了显得稍微专业一点,想把它们打包一个EXE文件执行,因为我见到到这样的程序,直接一个EXE程序,一点直接运行,顿时感觉好吊,于是乎,搜啊搜,搞定了,总结如下. 效果图: 原来的一坨文件 现在的一个单独的EXE文件,看起来就很吊的样子 第一步:打包 将所有的文件打包成一个RAR压缩包,没错,直接打成RAR包! 第二步:解压选项

在Winform开发框架中使用DevExpress的内置图标资源

在开发Winform程序界面的时候,我们往往会使用一些较好看的图表,以便能够为我们的程序界面增色,良好的图标设置可以让界面看起来更加美观舒服,而且也比较容易理解,图标我们可以通过一些网站获取各种场景的图标资源,不过本篇随笔主要介绍如何利用DevExpress的内置图标资源来实现界面图标的设置. 1.设计时刻的图标处理 丰富的图标处理,在菜单.工具栏.树列表等地方,以及按钮等地方,都可以使用,而这些我们可以利用DevExpress的内置图标选择来减轻我们寻找合适图标的烦恼. 一些按钮.工具栏等的图

Delph控制台(Console)程序添加图标和版权信息

Delphi创建控制台(Console)程序默认是无法添加图标和版权的.经过仔细的对比窗体程序与控制台程序源码,发现窗体程序的工程文中,在uses结束begin开始的地方有一句如下代码:{$R *.res}而控制台程序的工程文件里是没有这句代码的.于是,我就在想是不是我在控制台程序的工程文件里加上如上代码,我们就可以更改图标和添加版权了,说做就开始做,加上如上代码,然后保存,Delphi会自动生成资源文件,如下图:本以为可以就可以编辑图标和版权了,结果发现,版权是可以修改了,但是图标还是无法修改

【Cocos2d-Js基础教学(5)资源打包工具的使用及资源的异步加载处理】

[转载]http://www.cnblogs.com/zisou/p/cocos2dx-js5.html   TexturePacker是纹理资源打包工具,支持Cocos2dx的游戏资源打包. 如果用过的同学可以直接看下面的资源的异步加载处理 首先为什么用TexturePacker? 1,节省图片资源实际大小 2,减少我们游戏中大量资源带来的内存负荷 3,方便游戏对纹理资源的内存管理 游戏开发到后期,我们或许都会遇到的瓶颈就是需要对游戏包进行"瘦身"和内存优化.那么使用TextureP