`
hgfghww6
  • 浏览: 42099 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

flex动态生成矢量swf字体--java动态生成swf文件

 
阅读更多

  前言 相信很多在线设计的前端WEB应用会用到字体作为素材的案例,丰富多样的字体一般是部署在服务器端让用户去选择,而且能动态部署,使用客户端字体显然是不可取的;
  现状
  然而中文字体动不动就几个M,做过flash的同学应该知道嵌入字体是怎么回事,假如嵌入字体会使得swf整个体积变大,而flex目前容易做到的是整个字体文件编译成swf格式来动态加载。假如需要根据用户输入的文字动态的加载该如何做呢?
  最简单的方案是后台根据字体生产位图,这不能满足我的要求,1,位图拉伸后有锯齿2,大一点的位图文件很占空间,前台设计需要至少1000×1000以上才能保证清晰度,这么一张图动不动就大于100K。
  目的
  最完美的一个方案,是能让我的用户输入文字后,生成一个对应字体仅仅包含这几个文字的swf资源文件,这个swf占的空间很小并且在flex中用就可以加载。
  阿里妈妈bannermaker是有这个方案的,但是商业机密没有公开出来,可以肯定的是一定在后台端生成swf,至于怎么产生,目前也没找到过现成方案。只能自己研究了,经过一段时间实践,结合java动态生成swf的一个框架,终于成功了,20个文字的矢量图,10K不到,而且矢量图和字体大小无关,随便前端怎么拉伸无锯齿。
  首先,重述下动态矢量swf字体是什么含义呢?
  用户-》选择1字体并输入'abc'-》后台生成一个swf,这个swf仅仅包含1字体中abc三个字符并且是矢量的。
  类似于flash IDE里的这个功能:
  
  嵌入字体并导出资源swf图像。
  遗憾的是IDE不容易和应用整合,如何用代码来实现呢?
  实现的核心:java登场了,感谢anotherbigidea大师的开放和分享
  http://www.anotherbigidea.com/javaswf/
  这已经是anotherbigidea大师03年时候的杰作了,用java io操作 根据flash 6字节位组织方式可以从swf 1中提取任何的元素再去动态生成swf 2的内容。
  因此,一个想法诞生了,后台放置一个字体a的全量swf1文件,java端获取到用户输入的文字后动态的从swf1拷贝那几个图形文字生成一个 swf2 不就ok了么。 果然,如我所料:
  1,全量的swf字库怎么做?
  可依照上图,在本地安装字体后,嵌入所有字符导出一个swf,最好是swf 6.0格式。(flex和flash共享资源文件目前都用6)
  2,怎么用java动态生成swf?
  /**
  * 简单测试
  */
  package test;
  import java.io.BufferedInputStream;
  import java.io.BufferedReader;
  import java.io.File;
  import java.io.FileInputStream;
  import java.io.IOException;
  import java.io.StringReader;
  import java.util.HashMap;
  import com.anotherbigidea.flash.movie.Font;
  import com.anotherbigidea.flash.movie.FontDefinition;
  import com.anotherbigidea.flash.movie.FontLoader;
  import com.anotherbigidea.flash.movie.Frame;
  import com.anotherbigidea.flash.movie.Movie;
  import com.anotherbigidea.flash.movie.Text;
  import com.anotherbigidea.flash.movie.Font.NoGlyphExcepti on;
  import com.anotherbigidea.flash.structs.Color;
  /**
  * @author jianwen
  * @email  wen2375160@163.com  
  *
  */
  public class Testtxt {
  /**
  * @param args
  * @throws IOException 
  * @throws NoGlyphException 
  */
  public static void main(String[] args) throws IOException, NoGlyphException {
  //--Load a font from another movie.  That movie should contain only an
  // edit field that is specified to include all the glyphs in the
  // appropriate font.
  // Font definitions can be referenced by multiple fonts (for example if
  // there is a font used for a text block and another font used with an
  // edit field which restricts the allowable characters).
  //初始化 加载全量字库
  java.awt.Font nf = java.awt.Font.createFont(java.awt.Font.TRUETYPE_FO NT, new FileInputStream("c://mnjmb.ttf"));
  //第一步,输入文字
  String instr = "文字这个的房贷首付第三方第三方\n\n\n地方地方haha牛x第三方我祖国好地方\n地方\ndfdfdsf";
  //第二步:选择/导入字库
  /////////避免重复加载
  String fontpath = "ccxkt";
  HashMap fonts = new HashMap();
  FontDefinition fontdef = fonts.get(fontpath);
  System.out.println("当前使用内存:"+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024);
  if(fontdef==null){
  //导入swf格式的文字类库,注意路径
  fontdef = FontLoader.loadFont( "c://"+fontpath+".swf" ); //导入全量的字库,我这里有很多个,为了测试性能,发现一个中文字体要占30M左右的内存
  fonts.put(fontpath, fontdef);
  }
  //  File f = new File("c://ch");
  //  System.out.println("一共"+f.list().length+"个中文字体");
  //  for (String s :f.list()){
  //   System.out.print(s);
  //   fonts.put(s,FontLoader.loadFont("c://ch//"+s));
  //   System.out.println(":"+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024);
  //  }
  //  System.out.println("加载中文字体后内存2:"+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024);
  //  f = new File("c://en");
  //  System.out.println("一共"+f.list().length+"个英文字体");
  //  for (String s :f.list()){
  //   System.out.print(s);
  //   fonts.put(s,FontLoader.loadFont("c://en//"+s));
  //   System.out.println(":"+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024);
  //  }
  //  System.out.println("加载所有字体后内存3:"+(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory())/1024/1024);
  /////下面是动态生成文字对应的swf部分,性能很不错,io操作由于是内存拷贝,奇快无比,比后台动态用flex sdk编译方式还要快
  //初始化参数
  int fontsize = 100;//默认字体大小,由于矢量格式,大小没关系(swf文件大小不受此参数影响)
  Color c = new Color(0,0,0);//文字颜色
  //--Create a text object with a default transform
  Text text = new Text(null);
  //--The font references the Font Definition and pulls over only the 
  // glyph definitions that are required for any text referencing the font
  System.out.println("len1:"+fontdef.getGlyphList(). size());
  Font font = new Font( fontdef );
  //第四步:
  /////处理输入字符串,支持回车多行解析
  StringReader re = new StringReader(instr);
  BufferedReader bf = new BufferedReader(re);
  String s =  bf.readLine();
  int i=0;
  while(s!=null){
  //多行间必须使用空格
  if(s.length()==0){s = " ";}
  //--Add a row of characters - specify the starting (x,y) within the text symbol
  try {
  text.addRow(font.chars(s, fontsize), c, 0, fontsize * i + 5,true, true);
  } catch (NoGlyphException e) {
  // 某文字没有该对应字体,忽略
  }
  s = bf.readLine();
  i++;
  }
  /////解析完毕
  //--Add another row - different color, no (x,y) specified so the chars will
  // flow immediately after the preceding chars.
  // text.row( font.chars( "2我来无敌", 25), new Color(255,0,255),0,0,false,false);
  //计算文本框大小,重要,必须在movie初始化前 这是我改造的代码,先计算大小
  text.measureRect(null, null, font, false);
  //默认文字x=0, 推算出中文宽度需要多加一个单位的fontsize,偶也不知道为什么,加了没坏处
  Movie movie = new Movie( (int)text.maxX+fontsize,(int)(text.maxY-text.minY) ,12,5,null);
  Frame frame = movie.appendFrame();
  //--instantiate the text
  frame.placeSymbol( text, 0, -((int) text.minY ));//让文本框显示在0,0坐标
  //--save the movie
  movie.write( "c://output.swf",true );
  //输出到流
  //movie.write( OutputStream out, boolean compressed )
  }
  }
  最后,大师提供了一个基础,优化需继续
  这种方式生成的swf比通过flexsdk动态编译生成swf要快而且文件要小,精简,很多无用信息都不会生成。
  不过也有几个局限:
  1,字体swf必须导出flash 6格式, 只能提供了简单的动画接口。 
  2,后台导入的是一个全量swf库,占用静态内存极大,要部署50套字体的话 2G内存都不够;动态加载全量字体的话也是不可行的,因为加载一个全量字体花费极大,可考虑拆分部署,或者按字体文字的字节流引入数据库,再或者可按字体分布多个服务器部署。
  这个库已经很久没人更新了,里面的代码逻辑看得一头雾水,虽然功能和性能都通过了,但是基于继续大师的优化工作还有待继续前行。
  参考文献:
  http://www.anotherbigidea.com/javaswf/
分享到:
评论

相关推荐

    swf-file-format-spec.pdf.zip_flex_swf

    "swf-file-format-spec.pdf.zip_flex_swf" 提供了关于SWF文件格式的详细规范,这对于开发者尤其是使用Flex工具进行SWF开发的人来说至关重要。 首先,SWF文件是一种二进制文件格式,它包含了图形、音频、视频和...

    Flash(Flex)反编译及修改

    SWF文件是Flash Player理解和执行的二进制格式,包含了动画、音频、视频、字体和其他互动元素。它不包含原始的ActionScript代码,而是包含了经过优化和编译的指令。 3. **反编译工具**: 如描述中提到的"JPEXS Free...

    命令行下直接编译as文件为swf的方法

    - **编译结果**:成功执行上述命令后,会在当前目录下生成一个名为Test.swf的文件。如果希望将输出文件保存在其他位置,可以使用`-output`选项指定。 #### 2.3 创建批处理文件 为了方便重复执行相同的编译任务,...

    Flex中文帮助-1

    - Flex应用可以作为SWF文件嵌入到HTML页面,或者打包成独立的AIR应用(Adobe Integrated Runtime)在桌面运行。 10. **Flex安全** - 考虑到数据安全和应用安全,Flex应用需要处理身份验证、授权、加密等问题,这...

    把PDF文件转换为swf

    例如,`gkai00mp.ttf`是一个可能用于中文简体字的TrueType字体文件。如果PDF文件中使用了这个字体,转换软件需要确保SWF文件能正确显示这些字符。这可能需要将字体嵌入到SWF文件中,或者在目标环境中保证该字体可用...

    flex字体制作软件

    在Flash内容制作中,字体是传达信息的重要元素,而Flex字体制作软件则提供了一种创新的方式,让用户能够对字体进行个性化的设计,从而在SWF文件中创造出引人注目的文字效果。 首先,我们要理解Flash的字体渲染机制...

    Flex开发辅助工具

    Flex开发辅助工具是一系列专为Flex开发者设计的实用工具,主要以SWF(Shockwave Flash)格式提供。这些工具能够帮助开发者更有效地理解和利用Flex框架的功能,提高开发效率。下面将逐一详细介绍这些文件: 1. **...

    gif转swf和swf转gif工具

    SWF文件通常包含矢量图形,这使得它们在不同分辨率下都能保持清晰,而且文件大小相对较小,适合在线播放。 在某些情况下,可能需要将GIF转换为SWF。例如,如果希望创建一个更高效的动画,或者需要利用Flash的交互性...

    Flex基础培训讲义.ppt

    - 最后编译生成SWF文件,可在Flash Player中运行。 3. **关键点**: - **Controls**是可交互的组件,如按钮、文本框等。 - **Containers**是包含和管理其他组件的对象,如Panel、Canvas。 - **Effects**为组件...

    Flex中文学习.rar

    Flex是Macromedia发布的presentation server(展现服务),...Flex是通过java或者.net等非Flash途径,解释.mxml文件组织components,并生成相应得.swf文件。Flex的component和flash的component很相似,但是有所改进增强。

    解决swf文件复制到另外的电脑上打不开的问题

    SWF文件是Adobe Flash平台用于播放交互式矢量图形、视频和应用程序的文件格式。当用户尝试在不同的计算机上打开SWF文件时,可能会遇到无法正常播放的情况,这通常由以下几个原因造成: 1. **Flash Player版本不兼容...

    flex3使用说明

    Flex 是通过 Java 或者 .NET 等非 Flash 途径,解释 .mxml 文件组织 components,并生成相应的 .swf 文件。 四、为什么需要 Flex? Flex 的出现是为了迎合更多的开发者,吸引更多的 JSP/ASP/PHP 等程序员。Flex ...

    私人使用奉献 flex3注册机

    Flex是通过java或者.net等非Flash途径,解释.mxml文件组织components,并生成相应的.swf文件。Flex的component和flash的component很相似,但是有所改进增强。目前Macromedia公司已经被ADOBE公司收购。当前(2008年10...

    Flex-Menual-CHN.zip_flex_flex 官方文档

    1. SWF发布:通过Flex Compiler将源代码编译为SWF文件,可在Web浏览器中运行。 2. AIR应用:使用Adobe AIR SDK,可以创建桌面应用程序,提供更丰富的桌面级功能。 综上所述,Flex中文帮助文档全面涵盖了Flex的各个...

    Flex3 Java 中文教程

    10. **部署与发布**:最后,教程会教授如何打包和发布Flex应用程序,包括设置SWF参数、生成AIR应用程序和处理版本控制。 《Flex+3+Cookbook.pdf》这本书的具体章节可能详细地覆盖了以上这些主题,并提供了实用的...

    Flex 动态加载 Image 和 Icon 解决方案

    如果是矢量图形,你可能需要使用 `SWFLoader` 类来加载 SWF 文件,然后将其中的图形作为 Icon 使用。如果是位图 Icon,可以使用上述的 `Loader` 方法。此外,Flex 还提供了 `mx.controls.IconItem` 和 `mx.controls....

Global site tag (gtag.js) - Google Analytics