设为首页收藏本站

UNIX技术社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
热搜: console
查看: 1497|回复: 0

pdf2swf process阻塞问题

[复制链接]
发表于 2013-11-19 11:09:08 | 显示全部楼层 |阅读模式
SWFTools 是一组用来处理 Flash 的 swf 文件的工具包,包括:
1. 合并工具 swfcombine
2. 抽取工具 swfextract
3. PDF/JPEG/PNG/AVI/TTF/WAV 到 SWF 的转换工具 :pdf2swf, jpeg2swf, png2swf, avi2swf, font2swf, and wav2swf|
4. 文本解析工具 swfstrings
5. SWF 解析器 swfdump
6. SWF 读写库 rfxswflib
SWFTools提供了一系列将各种文件转成swf的工具:
font2swf.exe
gif2swf.exe
jpeg2swf.exe
pdf2swf.exe
png2swf.exe
wav2swf.exe
具体的功能就顾名思义了。
其中把pdf转成swf的工具就是pdf2swf了。在命令行中运行pdf2swf src.pdf des.swf一般能满足需求。而命令行参数可以通过pdf2swf -f得到:
-h , –help                      Print short help message and exit              打印帮助信息
-V , –version                Print version info and exit                        打印版本号
-o , –output file.swf         Direct output to file.swf. If file.swf contains ‘13568621′ (file13568630.swf), then each page指定输出的swf文件名
-p , –pages range             Convert only pages in range with range e.g. 1-20
or 1,4,6,9-11 or 指定转换的页面范围,使用的页码描述方法与打印机打印文件时候的选页一样
-P , –password password       Use password for deciphering the pdf.指定打开pdf的密码
-v , –verbose                 Be verbose. Use more than one -v for greater effect.转换时输出详细的内容
-z , –zlib                    Use Flash 6 (MX) zlib compression.使用Flash 6的zlib压缩机制
-i , –ignore                  Allows pdf2swf to change the draw order of the pdf. This may make the generated允许程序修改pdf的绘制顺序,可能会导致结果与原来有差异
-j , –jpegquality quality     Set quality of embedded jpeg pictures to quality. 0 is worst (small), 100 is best (big). (default:85)设置转换其中的jpeg图片的质量,从0到100,默认值是85。
-s , –set param=value         Set a SWF encoder specific parameter. See pdf2swf -s help for more information. 设置SWF转码时候的参数,具体参数可以用pdf2swf -s help获取
-w , –samewindow              When converting pdf hyperlinks, don’t make the links open a new window.        设置转换后的swf打开原pdf中的连接时使用相同的窗口
-t , –stop                    Insert a stop() command in each page.            在每页结尾添加一个stop()命令
-T , –flashversion num        Set Flash Version in the SWF header to num.         设置SWF所使用的flash版本号
-F , –fontdir directory       Add directory to the font search path.                    指定字体文件所在路径
-b , –defaultviewer           Link a standard viewer to the swf file.             指定默认的swf导航文件,用来翻页、放大缩小等等
-l , –defaultloader           Link a standard preloader to the swf file which will be displayed while the main swf is loading.     指定默认的swf加载文件,用来显示加载进程效果
-B , –viewer filename         Link viewer filename to the swf file.   指定swf导航文件,作用同-b
-L , –preloader filename      Link preloader filename to the swf file.      指定swf加载文件,作用同-l
-q , –quiet                   Suppress normal messages. Use -qq to suppress warnings, also. 不打印普通信息,用-qq就不打印警告信息。
-S , –shapes                  Don’t use SWF Fonts, but store everything as shape. 不使用字体,所有都转为形状。
-f , –fonts                   Store full fonts in SWF. (Don’t reduce to used characters). 在swf中保存全部字体。
-G , –flatten                 Remove as many clip layers from file as possible. 在文件中尽量去除影片层,合并它们
-I , –info                    Don’t do actual conversion, just display a list of all pages in the PDF. 不做实际转换,仅显示PDF的信息。
-Q , –maxtime n               Abort conversion after n seconds. Only available on Unix. 如果运行时间超时则退出。
然后看看-s都可以设置些什么:
PDF Parameters:
PDF device global parameters:
fontdir= a directory with additional fonts 指定字体目录, 与1级参数的-F相若
font= an additional font filename 增加额外的字体文件
pages= the range of pages to convert (example: pages=1-100,210-) 指定页面范围,与1级参数的-p相若
zoom= the resolution (default: 72) 指定分辨率,默认为72dpi
languagedir= Add an xpdf language directory 增加一个xpdf的语言目录,对非西欧字符有用
multiply= Render everything at the resolution 在几倍分辨率下渲染
poly2bitmap Convert graphics to bitmaps 把其中的图形转成点阵
bitmap Convert everything to bitmaps 把所有内容转成点阵(包括字体) SWF Parameters:
SWF layer options:
jpegsubpixels=<pixels> resolution adjustment for jpeg images (same as jpegdpi, but in pixels) jpeg图片的分辨率
ppmsubpixels=<pixels> resolution adjustment for lossless images (same asppmdpi, but in pixels) 无损图片的分辨率
subpixels=<pixels>     shortcut for setting both jpegsubpixels and ppmsubpixels 快速设置上两个参数
drawonlyshapes           convert everything to shapes (currently broken) 所有都转成图形
ignoredraworder         allow to perform a few optimizations for creating smaller SWFs 允许执行一些小优化
linksopennewwindow   make links open a new browser window 链接打开新窗口
linktarget                  target window name of new links       新链接窗口的名称
linkcolor=<color)        color of links (format: RRGGBBAA)    链接的颜色
linknameurl         Link buttons will be named like the URL they refer to (handy for iterating through links with actionscript) 链接名称与链接URL一致
storeallcharacters      don’t reduce the fonts to used characters in the output file 保存所有的字符字体
enablezlib                switch on zlib compression (also done if flashversion>=7) 使用zlib压缩
bboxvars                 store the bounding box of the SWF file in actionscript variables 在as中保存swf的区域大小
dots                        Take care to handle dots correctly 保存单点显示
reordertags=0/1     (default: 1) perform some tag optimizations 执行某些tag优化
internallinkfunction=<name> when the user clicks a internal link (to a different page) in the converted file, this actionscript function is called 内部链接函数,如果点击一个内部链接,将调用该actionscript函数
externallinkfunction=<name> when the user clicks an external link (e.g. http://www.foo.bar/) on the converted file, this actionscript function is called 外部链接函数,如果点击一个外部链接,将调用该actionscript函数
disable_polygon_conversion never convert strokes to polygons (will remove capstyles and joint styles) 不要将笔画转成多边形
caplinewidth=<width>        the minimum thichness a line needs to have so that capstyles become visible (and are converted)           线条最低转换宽度,比这个细的线条将不转换
insertstop                  put an ActionScript “STOP” tag in every frame 在swf的每个桢中添加stop()函数
protect                     add a “protect” tag to the file, to prevent loadingin the Flash editor 增加protect标签,禁止在flash中加载该swf
flashversion=<version> the SWF fileversion (6) 设置最低swf版本
framerate=<fps>         SWF framerate 设置桢率
minlinewidth=<width> convert horizontal/vertical boxes smaller than thiswidth to lines (0.05)将宽度少于某值的矩形转成线条
simpleviewer     Add next/previous buttons to the SWF 使用简单的导航
animate           insert a showframe tag after each placeobject (animate draw order of PDF files) ???
jpegquality=<quality> set compression quality of jpeg images 设置jpeg的压缩质量
splinequality=<value> Set the quality of spline convertion to value (0-100, default: 100). 设置样条曲线的转换质量
disablelinks                Disable links. 禁止链接
在含中文的pdf转换时会遇到一些麻烦,具体的解决方法:(javaeye上的文字)
1. 下载swftools:http://www.swftools.org/download.html 下载xpdf xpdf-chinese-simplified
下载两个中文字体文件 字体文件
2 .安装swftools 至任意路径
解压缩xpdf 至任意路径
解压缩中文字体至xdpf/chinese-simplified/CMap文件夹下
3. 修改xpdf下xpdfrc文件 将cidToUnicode 等路径改为本机路径,
修改xpdf下chinese-simplified/add-to-xpdfrc文件 同上
4. 打开命令行窗口: pdf2swf -o 输出文件路径 -t 输入文件路径 -s languagedir=xpdf路径/chinese-simplified
有些pdf中的图形转换效果不好,会产生过多shape,这种情况下可以使用 -s poly2bitmap 的参数,将图形转成点阵。生成的swf尺寸少了。
问题:
当处理一个中文文档时出问题了:
Couldn’t find a font for ‘黑体’
这个文档的字体编码是“GBK-EUC-H”, 实际字体是黑体,类型是TrueType(CID)。
解决:
1.从复制一个simhei.ttf到xdpf/chinese-simplified/CMap下,
2.修改修改xpdf下xpdfrc文件,增加一行:displayCIDFontTT Adobe-GB1 simhei.ttf的路径


引用
因为项目需要,这几天在研究仿百度文库的一个例子。网上搜索了一下,发现基本上都是一个思路:先通过 openoffice 和 jodconverter 将office等文档转换为 pdf ,然后再通过java.lang.process 调用 swftools 程序将 pdf 转换为 swf。最后就可以利用 flexpaper 将生成的 swf 显示出来了,效果和百度文库差不多。
思路上没有问题,但是在具体做的时候遇到了一个java.lang.process 阻塞的问题,就是在调用 java process 来启动 swf 转换文件时一直不能生成 pdf,后来自己摸索的好久也没明白是什么问题,无意中找到了一个关于java进程阻塞问题的帖子。后来才知道,通过java.lang.process 调用本地程序的时候,需要将 process 缓存中的输出信息读取出来,不然就会造成进程的阻塞。
  
这两天一直在处理flv视频环境的搭建工作,包括服务器的安装和java中的应用。安装ffmpeg加mencoder倒没有什么大问题,不过还是有一个小问题弄得我郁闷了下,就是在安装amrwb和amrnb的时候出错,错误如下:
/usr/bin/wget -N http://www.3gpp.org/ftp/Specs/ar ... 6.104/26104-610.zip
--20:41:59--  http://www.3gpp.org/ftp/Specs/ar ... 6.104/26104-610.zip
正在解析主机 www.3gpp.org... 212.234.161.21
Connecting to www.3gpp.org|212.234.161.21|:80... 已连接。
已发出 HTTP 请求,正在等待回应... 403 Forbidden
20:42:00 错误 403:Forbidden。
make: *** [26104-610.zip] 错误 1
    后来仔细看了和问了下公司的网络管理员,才知道我这台测试机器没有开外网,刚开始也想到了是这个问题,可ping的时候却可以ping通,所以就放弃了那个想法,谁知道还真是这问题,结果就好说咯,开通网络后安装就非常顺利了~~~这是题外话了,呵
    ffmpeg的环境搭建起来后,在本地进行手动转换没什么问题,通过程序调用(不获取程序反馈结果)也没什么问题。可后来进一步深入的时候,我在提交视频的转换请求的时候,必然要进行数据库的相关操作,比如在转换前更新该视频的状态为正在更新状态,在转换完毕后填如该视频的flv文件路径和图片路径信息,还有flv文件的大小和时间长度等等数据。这就需要在线程中控制ffmpeg进程的状态了,这里我们就需要用到Process这个类了,典型的我们写代码如下:
……
Process process = Runtime.getRuntime.exec(cmd); // 执行调用ffmpeg命令
InputStream is = process.getInputStream(); // 获取ffmpeg进程的输出流
BufferedReader br = new Buffered(new InputStreamReader(is)); // 缓冲读入
StringBuilder buf = new StringBuilder(); // 保存ffmpeg的输出结果流
String line = null;
while((line = br.readLine()) != null) buf.append(line); // 循环等待ffmpeg进程结束
System.out.println("ffmpeg输出内容为:" + buf);
……
    本来一般都是这样来调用程序并获取进程的输出流的,但是我在windows上执行这样的调用的时候却总是在while那里被堵塞了,结果造成ffmpeg程序在执行了一会后不再执行,这里从官方的参考文档中我们可以看到这是由于缓冲区的问题,由于java进程没有清空ffmpeg程序写到缓冲区的内容,结果导致ffmpeg程序一直在等待。在网上也查找了很多这样的问题,不过说的都是使用单独的线程来进行控制,我也尝试过很多网是所说的方法,可一直没起什么作用。下面就是我的解决方法了,注意到上述代码中的红色部分了么?这里就是关键,我把它改成如下结果就可以正常运行了。
InputStream is = process.getErrorStream(); // 获取ffmpeg进程的输出流
    注意到没?我把它改成获取错误流这样进程就不会被堵塞了,而我之前一直想的是同样的命令我手动调用的时候可以完成,而java调用却总是完成不了,一直认为是getInputStream的缓冲区没有被清空,不过问题确实是缓冲区的内容没有被清空,但不是getInputStream的,而是getErrorStream的缓冲区,这样问题就得到解决了。所以我们在遇到java调用外部程序而导致线程阻塞的时候,可以考虑使用两个线程来同时清空process获取的两个输入流,如下这段程序:
……
Process process = Runtime.getRuntime.exec(command); // 调用外部程序
final InputStream is1 = process.getInputStream();
new Thread(new Runnable() {
    public void run() {
        BufferedReader br = new Buffered(new InputStreamReader(is));
        while(br.readLine() != null) ;
    }
}.start(); // 启动单独的线程来清空process.getInputStream()的缓冲区
InputStream is2 = process.getErrorStream();
BufferedReader br2 = new Buffered(new InputStreamReader(is2));
StringBuilder buf = new StringBuilder(); // 保存输出结果流
String line = null;
while((line = br.readLine()) != null) buf.append(line); // 循环等待ffmpeg进程结束
System.out.println("输出结果为:" + buf);
……
    通过这样我们使用一个线程来读取process.getInputStream()的输出流,使用另外一个线程来获取process.getErrorStream()的输出流,这样我们就可以保证缓冲区得到及时的清空而不担心线程被阻塞了。当然根据需要你也可以保留process.getInputStream()流中的内容,这个就看调用的程序的处理了。我在windows下调用FFmpeg程序进行视频转换的时候就是通过这样来解决线程被堵塞的问题的,呵呵~

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表