java - 如何使用Java知道SWF文件的原始大小(宽度和高度)?

标签 java flash size dimensions

有没有办法用java知道swf文件的原始宽度和高度?

int width, height;

// my stream contains an image or a swf file
InputStream stream = file.getInputStream();

// mediaType has been set with the help of file extension 
switch (mediaType)
{
    case IMAGE:
        BufferedImage img = ImageIO.read(stream);
        width = img.getWidth();
        height = img.getHeight();
        break;
    case FLASH:
        // what is the code here ?
        break;
}

最佳答案

我看了布鲁克斯的资源,有点不知所措,所以我写了自己的“一个顶级类(class)”解决方案。我知道这篇文章写得很长,但是不知道如何发布。

软件包resnbl.android.swfview;

导入java.io.File;
导入java.io.FileInputStream;
导入java.io.IOException;
导入java.util.Arrays;
导入java.util.zip.DataFormatException;
导入java.util.zip.Inflater;

/**
*此类将仅读取SWF文件的标题足以收集必要的内容
*有关动画的元数据。
*
*这是基于
* SWF文件格式规范(版本10)

*
* @author Resnbl软件
* @自2011年3月22日起
*/
公共(public)类SWFInfo
{
静态最终整数UNCOMP_HDR_LEN = 8;//永远不会压缩的 header 部分

public boolean isCompressed;
公共(public)int版本;
公共(public)长尺寸;
public int宽度,高度;
公众持股量
public int frameCount;

//通过getInfo()方法实例化
私有(private)SWFInfo()
{}

/**
*获取由文件路径String指定的(潜在)SWF文件的标题信息。
*
* @param path包含文件路径的字符串。
*
* @return {@link SWFinfo}对象;如果找不到文件或没有SWF,则返回null。
*/
公共(public)静态SWFInfo getInfo(字符串路径)
{
返回getInfo(new File(path));
}

/**
*获取由{@link File}对象指定的(潜在)SWF文件的标题信息。
*
* @param路径{@link File}指向所需的SWF文件。
*
* @return {@link SWFinfo}对象;如果找不到文件或没有SWF,则返回null。
*/
公共(public)静态SWFInfo getInfo(文件文件)
{
SWFInfo info =新的SWFInfo();
byte [] hdr = getBytes(file);

如果(hdr == null)
返回null;
info.isCompressed = hdr [0] =='C';
info.version = hdr [3];
info.size = hdr [4]&0xFF | (hdr [5]&0xFF)<< 8 | (hdr [6]&0xFF)<< 16 | hdr [7] << 24;

BitReader rdr =新的BitReader(hdr,UNCOMP_HDR_LEN);

int []暗=解码Rect(rdr);
info.width =(dims [1]-dims [0])/20;//将缇转换为像素
info.height =(dims [3]-dims [2])/20;

info.fps =(float)rdr.uI16()/256f;//8.8定点格式
info.frameCount = rdr.uI16();

返回信息;
}

/*
*仅出于我们的目的读取了足够的文件
*/
私有(private)静态字节[] getBytes(文件文件)
{
if(文件== null ||!file.exists()|| file.isDirectory())
返回null;

byte []个字节=新的字节[128];//应该足够了...
FileInputStream fis = null;

尝试
{
fis =新的FileInputStream(file);

如果(fis.read(bytes) 字节=空;//太少的字节不能用作SWF
否则if(bytes [0] =='C'&& bytes [1] =='W'&& bytes [2] =='S')
字节=扩展(字节,UNCOMP_HDR_LEN);//压缩的SWF
否则if(bytes [0]!='F'|| bytes [1]!='W'|| bytes [2]!='S')
字节=空;//不是SWF
//其他未压缩的SWF
}
捕获(IOException e)
{}
最后
{
如果(fis!= null)
尝试{fis.close(); }
捕获(IOException ee){}
}

返回字节;
}

/*
*压缩所有超出初始{@link UNCOMP_HDR_LEN}字节的文件。
*尽可能多地解压缩已读取的缓冲区并返回它们,
*覆盖原始的未压缩数据。
*
*幸运的是,Flash使用的压缩算法是ZLIB标准,
*,即用于压缩.jar文件的相同算法
*/
私有(private)静态字节[]扩展(字节[]字节,整数跳过)
{
byte [] newBytes =新的byte [bytes.length-跳过];
Inflater inflater = new Inflater();

inflater.setInput(bytes,skip,newBytes.length);
尝试
{
int outCount = inflater.inflate(newBytes);
System.arraycopy(newBytes,0,字节,跳过,outCount);
Arrays.fill(bytes,skip + outCount,bytes.length,(byte)0);
返回字节;
}
捕获(DataFormatException e)
{}

返回null;
}

/**
* Return Stage框架矩形为4 int s:LRTB
*
*请注意,这些值以TWIPS(=像素的1/20)为单位
*
*我这样做是为了避免加载 Rect 类,该类是
* android.graphics 类,如果要,则不可用
*使用桌面Java进行测试。
*
* @参数rdr
* @返回
*/
公共(public)静态int [] encodeRect(BitReader rdr)
{
int [] dims = new int [4];
int nBits = rdr.uBits(5);

dims [0] = rdr.sBits(nBits);//X min =始终为0
dims [1] = rdr.sBits(nBits);//X max =右
dims [2] = rdr.sBits(nBits);//Y min =顶部始终为0
dims [3] = rdr.sBits(nBits);//Y max =底部

返回暗淡;
}

/**
*这可以从位于.../bin目录中的桌面命令行运行,如下所示:
*
* java resnbl.android.swfview.SWFInfo swf_file
*
* @param args解析到swf_file的路径
*/
//注释掉以防止Eclipse认为这是用于Android的标准Java应用程序!
//公共(public)静态void main(String [] args)
//{
//如果(args.length == 0)
//抛出新的IllegalArgumentException(“未提供swf_file参数”);
//
//File file = new File(args [0]);
//SWFInfo info = SWFInfo.getInfo(file);
//
//如果(info!= null)
//{
//System.out.println(“File:” + file);
//System.out.println(“Flash ver:” + info.version +“FPS:” + info.fps +“Frames:” + info.frameCount);
//System.out.println(“文件大小:” + file.length()+“压缩后:” + info.isCompressed +“未压缩后的大小:” + info.size);
//System.out.println(“Dimensions:” + info.width +“x” + info.height);
//}
// 别的
//System.out.println(“文件不是.SWF:” +文件);
//}

/**
*从byte []中读取任意数量的位。
*
*这应该变成功能齐全的独立类(某天……)。
*/
静态类BitReader
{
专用byte []个字节;
private int byteIdx;
private int bitIdx = 0;

/**
*从提供的数组的开头开始读取。
* @param bytes byte []要处理
*/
公共(public)BitReader(byte []个字节)
{
this(bytes,0);
}

/**
*开始从任意索引读入数组。
* @param bytes byte []要处理
* @param startIndex字节#开始于
*/
公共(public)BitReader(byte [] bytes,int startIndex)
{
this.bytes =字节;
byteIdx = startIndex;
}

/**
*获取下一个 bitCount 位作为一个无符号的int。
* @param bitCount#要读取的位
* @return int
*/
公共(public)int uBits(int bitCount)
{
int值= 0;

而(--bitCount> = 0)
值=值<< 1 | getBit();
返回值;
}

/**
*获取下一个 bitCount 位作为 signed 整数。
* @param bitCount#要读取的位
* @return int
*/
公共(public)int sBits(int bitCount)
{
//第一位是“sign”位
int value = getBit()== 0吗? 0:-1;
--bitCount;

而(--bitCount> = 0)
值=值<< 1 | getBit();
返回值;
}

//获取数组中的下一位
私有(private)int getBit()
{
int值=(bytes [byteIdx] >>(7-bitIdx))&0x01;

如果(++ bitIdx == 8)
{
bitIdx = 0;
++ byteIdx;
}

返回值;
}

/**
*获取接下来的2个“整个”字节作为一个无符号的int(小尾数)。
* @return int
*/
公开intuI16()
{
同步();//返回“字节对齐”模式
返回(字节[byteIdx++]和0xff)| (bytes [byteIdx++]&0xff)<< 8;
}

/**
*将索引凸出到下一个字节边界。
*/
公共(public)无效sync()
{
如果(bitIdx> 0)
{
++ byteIdx;
bitIdx = 0;
}
}
}
}

注意:我用它们的HTML等效项全局替换了尖括号,以使其正确显示。如果您将其剪切并粘贴,则希望您不必还原该更改。

关于java - 如何使用Java知道SWF文件的原始大小(宽度和高度)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5030971/

相关文章:

java - 使用ehcache的Bean无法注入(inject)

java - 获取包中具有特定注释的所有方法

java - 2 个提交按钮 - 不同的查询,

android - Flash 游戏 - 返回主菜单

apache-flex - Flash:带有引用表的 AMF3?

c - 如何在预处理器时间内计算数组大小?

JQuery float 饼图大小错误

Java:Swing 中的 HTML,链接边距不起作用

flash.net.URLLoader 从 500 内部服务器错误中获取正文

javascript - 为什么我在 jquery 中的 if 语句不能检测图像大小?