- 浏览: 42099 次
- 性别:
- 来自: 上海
最新评论
前言 相信很多在线设计的前端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/
发表评论
-
格式化字符串攻击原理及示例
2012-07-06 09:51 631一、类printf函数簇 ... -
12章 正则表达式
2012-07-06 09:45 782笔记: 1. 正则表达式是一种"表示法&q ... -
全面分析Linux正则表达式(三)
2012-07-06 09:37 590Linux正则表达式的 ... -
C#实现屏幕录像 网上看到的看起来不错
2012-07-06 09:30 1664using System; using System. ... -
实现google的下拉列表效果
2012-07-05 20:45 799 -
Wix使用笔记(七) 添加系统必备组件的安装程序
2012-07-03 13:43 1319我们知道在vs的打包工程中添加系统必备组件是一件很容易的事 ... -
使用Flex和Actionscript开发Flash游戏――碰撞检测
2012-07-02 10:32 560这一部分,我们加 ... -
flex+blazeds+java(将java整合到flex中)
2012-07-02 10:32 579最近项目中需要Flex与Java进行通信,初步选定使用Bl ... -
Flex 捆绑式验证处理
2012-07-02 10:32 569Flex提供的默认的验证器,比如:日期验证器、货币验证器等 ... -
flex用弹出窗体展示gif
2012-07-02 10:31 518GIFPlayer用于在flex中展示GIF图片。 ... -
Flex4 中使用ModuleLoader为子容器 动态加入到TabNavigator导航器容器中的例子
2012-07-01 00:10 604经常在一些工程中看到 选择左侧目录树 右侧添加TAB加载内 ... -
flex用弹出窗体展示gif
2012-07-01 00:10 585GIFPlayer用于在flex中展示GIF图片。 ... -
为什么使用Flex库
2012-07-01 00:10 570上个星期,我写了 ... -
Flex 遍历组件的实现
2012-07-01 00:10 723Flex有两个阵营组件:spark组件和mx组件,关于sp ...
相关推荐
"swf-file-format-spec.pdf.zip_flex_swf" 提供了关于SWF文件格式的详细规范,这对于开发者尤其是使用Flex工具进行SWF开发的人来说至关重要。 首先,SWF文件是一种二进制文件格式,它包含了图形、音频、视频和...
SWF文件是Flash Player理解和执行的二进制格式,包含了动画、音频、视频、字体和其他互动元素。它不包含原始的ActionScript代码,而是包含了经过优化和编译的指令。 3. **反编译工具**: 如描述中提到的"JPEXS Free...
- **编译结果**:成功执行上述命令后,会在当前目录下生成一个名为Test.swf的文件。如果希望将输出文件保存在其他位置,可以使用`-output`选项指定。 #### 2.3 创建批处理文件 为了方便重复执行相同的编译任务,...
- Flex应用可以作为SWF文件嵌入到HTML页面,或者打包成独立的AIR应用(Adobe Integrated Runtime)在桌面运行。 10. **Flex安全** - 考虑到数据安全和应用安全,Flex应用需要处理身份验证、授权、加密等问题,这...
例如,`gkai00mp.ttf`是一个可能用于中文简体字的TrueType字体文件。如果PDF文件中使用了这个字体,转换软件需要确保SWF文件能正确显示这些字符。这可能需要将字体嵌入到SWF文件中,或者在目标环境中保证该字体可用...
在Flash内容制作中,字体是传达信息的重要元素,而Flex字体制作软件则提供了一种创新的方式,让用户能够对字体进行个性化的设计,从而在SWF文件中创造出引人注目的文字效果。 首先,我们要理解Flash的字体渲染机制...
Flex开发辅助工具是一系列专为Flex开发者设计的实用工具,主要以SWF(Shockwave Flash)格式提供。这些工具能够帮助开发者更有效地理解和利用Flex框架的功能,提高开发效率。下面将逐一详细介绍这些文件: 1. **...
SWF文件通常包含矢量图形,这使得它们在不同分辨率下都能保持清晰,而且文件大小相对较小,适合在线播放。 在某些情况下,可能需要将GIF转换为SWF。例如,如果希望创建一个更高效的动画,或者需要利用Flash的交互性...
- 最后编译生成SWF文件,可在Flash Player中运行。 3. **关键点**: - **Controls**是可交互的组件,如按钮、文本框等。 - **Containers**是包含和管理其他组件的对象,如Panel、Canvas。 - **Effects**为组件...
Flex是Macromedia发布的presentation server(展现服务),...Flex是通过java或者.net等非Flash途径,解释.mxml文件组织components,并生成相应得.swf文件。Flex的component和flash的component很相似,但是有所改进增强。
SWF文件是Adobe Flash平台用于播放交互式矢量图形、视频和应用程序的文件格式。当用户尝试在不同的计算机上打开SWF文件时,可能会遇到无法正常播放的情况,这通常由以下几个原因造成: 1. **Flash Player版本不兼容...
Flex 是通过 Java 或者 .NET 等非 Flash 途径,解释 .mxml 文件组织 components,并生成相应的 .swf 文件。 四、为什么需要 Flex? Flex 的出现是为了迎合更多的开发者,吸引更多的 JSP/ASP/PHP 等程序员。Flex ...
Flex是通过java或者.net等非Flash途径,解释.mxml文件组织components,并生成相应的.swf文件。Flex的component和flash的component很相似,但是有所改进增强。目前Macromedia公司已经被ADOBE公司收购。当前(2008年10...
1. SWF发布:通过Flex Compiler将源代码编译为SWF文件,可在Web浏览器中运行。 2. AIR应用:使用Adobe AIR SDK,可以创建桌面应用程序,提供更丰富的桌面级功能。 综上所述,Flex中文帮助文档全面涵盖了Flex的各个...
10. **部署与发布**:最后,教程会教授如何打包和发布Flex应用程序,包括设置SWF参数、生成AIR应用程序和处理版本控制。 《Flex+3+Cookbook.pdf》这本书的具体章节可能详细地覆盖了以上这些主题,并提供了实用的...
如果是矢量图形,你可能需要使用 `SWFLoader` 类来加载 SWF 文件,然后将其中的图形作为 Icon 使用。如果是位图 Icon,可以使用上述的 `Loader` 方法。此外,Flex 还提供了 `mx.controls.IconItem` 和 `mx.controls....