菜鸟进场,方圆十里,寸草不生

最近定制化一个app,需要显示wmf的文件,但是Android上无法对这种文件的直接显示,所以就需要对文件进行一个转换,网上对这方面的需求很少,所以简单的记录一下,就讲讲这里面的坑。

1、思路
首先,wmf是一种矢量图,而Android上说到矢量图想到什么呢?当然是svg图了,所以基本的思路就是将wmf转换为svg,然后再在Android上显示。

2、流程
(1)先通过jar包将wmf的图转化为svg,使用jar包:wmf2svg-0.9.6.jar
https://download.csdn.net/download/version1_0/10765431
使用代码:

  /** * @param file   wmf文件的位置 * @param dest   转换出来的svg文件的保存位置 */  private void convert(String file, String dest) throws Exception {        InputStream in = new FileInputStream(file);        WmfParser parser = new WmfParser();        final SvgGdi gdi = new SvgGdi(false);        parser.parse(in, gdi);        Document doc = gdi.getDocument();        OutputStream out = new FileOutputStream(dest);        if (dest.endsWith(".svgz")) {            out = new GZIPOutputStream(out);        }        output(doc, out);    }    private void output(Document doc, OutputStream out) throws Exception {        TransformerFactory factory = TransformerFactory.newInstance();        Transformer transformer = factory.newTransformer();        transformer.setOutputProperty(OutputKeys.METHOD, "xml");        transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");        transformer.setOutputProperty(OutputKeys.INDENT, "yes");        transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "-//W3C//DTD SVG 1.0//EN");        transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd");        transformer.transform(new DOMSource(doc), new StreamResult(out));        ByteArrayOutputStream bos = new ByteArrayOutputStream();        transformer.transform(new DOMSource(doc), new StreamResult(bos));        out.flush();        out.close();    }

备注:这里转换出来的文件在浏览器上已经可以访问了,但是在Android上不能访问。通过网上查询得知,这个转换出来的文件格式其实是svgz,这个svgz格式其实是svg的zip压缩包,但是这个压缩方式并不是普通的压缩方式,而是gzip方式压缩,需要解压。

(2)解压缩(这里附一个gzip格式压缩包的工具类)

public class GzipUtils {    public static final int BUFFER = 1024;    public static final String EXT = ".gz";    /**     * 数据压缩     */    public static byte[] compress(byte[] data) throws Exception {        ByteArrayInputStream bais = new ByteArrayInputStream(data);        ByteArrayOutputStream baos = new ByteArrayOutputStream();        // 压缩        compress(bais, baos);        byte[] output = baos.toByteArray();        baos.flush();        baos.close();        bais.close();        return output;    }    /**     * 文件压缩     */    public static void compress(File file) throws Exception {        compress(file, true);    }    /**     * 文件压缩     */    public static void compress(File file, boolean delete) throws Exception {        FileInputStream fis = new FileInputStream(file);        FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);        compress(fis, fos);        fis.close();        fos.flush();        fos.close();        if (delete) {            file.delete();        }    }    /**     * 数据压缩     */    public static void compress(InputStream is, OutputStream os) throws Exception {        GZIPOutputStream gos = new GZIPOutputStream(os);        int count;        byte data[] = new byte[BUFFER];        while ((count = is.read(data, 0, BUFFER)) != -1) {            gos.write(data, 0, count);        }        gos.finish();        gos.flush();        gos.close();    }    /**     * 文件压缩     */    public static void compress(String path) throws Exception {        compress(path, true);    }    /**     * 文件压缩     */    public static void compress(String path, boolean delete) throws Exception {        File file = new File(path);        compress(file, delete);    }    /**     * 文件压缩     */    public static void compress(String inputFileName, String outputFileName) throws Exception {        FileInputStream inputFile = new FileInputStream(inputFileName);        FileOutputStream outputFile = new FileOutputStream(outputFileName);        compress(inputFile, outputFile);        inputFile.close();        outputFile.flush();        outputFile.close();    }    /**     * 数据解压缩     */    public static byte[] decompress(byte[] data) throws Exception {        ByteArrayInputStream bais = new ByteArrayInputStream(data);        ByteArrayOutputStream baos = new ByteArrayOutputStream();        // 解压缩        decompress(bais, baos);        data = baos.toByteArray();        baos.flush();        baos.close();        bais.close();        return data;    }    /**     * 文件解压缩     */    public static void decompress(File file) throws Exception {        decompress(file, true, null);    }    /**     * 文件解压缩     */    public static void decompress(File file, boolean delete, String outPath) throws Exception {        FileInputStream fis = new FileInputStream(file);        FileOutputStream fos = null;        if (outPath == null || outPath == "") {            fos = new FileOutputStream(file.getPath().replace(EXT, ""));        } else {            File files = new File(outPath);            //判断文件是否存在,不存在,则创建            if(!files.exists()){                files.mkdirs();            }            //文件输出流参数中,需要指定文件解压后的文件名,这里,用文件的原名称            fos = new FileOutputStream(outPath + File.separator + file.getName().replace(EXT, ""));        }        decompress(fis, fos);        fis.close();        fos.flush();        fos.close();        if (delete) {            file.delete();        }    }    /**     * 文件解压缩     */    public static void decompress(String inputFileName, String outputFileName) throws Exception {        FileInputStream inputFile = new FileInputStream(inputFileName);        FileOutputStream outputFile = new FileOutputStream(outputFileName);        decompress(inputFile, outputFile);        inputFile.close();        outputFile.flush();        outputFile.close();    }    /**     * 数据解压缩     */    public static void decompress(InputStream is, OutputStream os) throws Exception {        GZIPInputStream gis = new GZIPInputStream(is);        int count;        byte data[] = new byte[BUFFER];        while ((count = gis.read(data, 0, BUFFER)) != -1) {            os.write(data, 0, count);        }        gis.close();    }    /**     * 文件解压缩     */    public static void decompress(String path) throws Exception {        decompress(path, true, null);    }    /**     * 文件解压缩(解压单个文件)     */    public static void decompress(String path, boolean delete, String outPath) throws Exception {        File file = new File(path);        decompress(file, delete, outPath);    }}

(3)、将svg图显示到Android上,目前网络上有直接显示svg图片的框架,而不需要通过Android studio自带的插件进行转换,这个框架就是:

//直接展示svg格式的图片    implementation 'com.pixplicity.sharp:library:1.1.0'

使用方式:

//展示到photoview                Sharp.loadFile(new File(file3) + ".1.svg").into(ivMap);

备注:到目前为止,可能有些svg图已经能够显示了,但是还有一些无法进行显示,原因是svg图里面可能带有style属性,而这个框架无法识别这个属性,就需要将这个属性里面的东西都设置到svg的文件中。(如果不理解的可以通过txt将svg打开,就知道什么原因了)
我这里写了一个,可能不是很规范,但能用吧,就先用着。

/** * 将style文件放到 */private void setStyle(File file) {    if (!file.exists() && file.isDirectory()) {        return;    }    BufferedWriter bw = null;    BufferedReader br = null;    try {        br = new BufferedReader(new FileReader(file));        File outFile = new File(file.getAbsolutePath() + ".1.svg");        bw = new BufferedWriter(new FileWriter(outFile));        //字符数组循环读取        String style = "";        boolean flag = false;        String str = null;        while ((str = br.readLine()) != null) {            bw.write(str + "\n");            if (str.indexOf("style") != -1) {                flag = !flag;            }            if (flag) {                style += str;            }            if (!flag && !TextUtils.isEmpty(style)) {                break;            }        }        Map map = new HashMap();        //去除里面的空格和换行        style = style.replaceAll("\n", "");        style = style.replaceAll(" ", "");        if (!TextUtils.isEmpty(style)) {            //切出所有的属性            String[] styles = style.split(">");            if (!TextUtils.isEmpty(styles[1])) {                String[] styles1 = styles[1].split("<");                if (!TextUtils.isEmpty(styles1[0])) {                    //按.将所有的属性隔开                    String[] styles2 = styles1[0].split("\\.");                    for (int i = 0; i < styles2.length; i++) {                        String data = styles2[i];                        if (!TextUtils.isEmpty(data)) {                            //按大括号切出属性值                            String[] data1 = data.split("\\{");                            String[] data2 = data1[1].split("\\}");                            //转换属性的文件样式                            String value = data2[0].replaceAll(":", "=\"");                            value = value.replaceAll(";", "\" ");                            map.put(data1[0], value);                        }                    }                }            }        }        //写出到磁盘        str = null;        while ((str = br.readLine()) != null) {            if (str.indexOf("class") != -1) {                //去掉以前的class属性标识                String[] str1 = str.split("\"");                String[] type = str1[1].split(" ");                str = str.replaceAll("class=\"", "");                for (int i = 0; i < type.length; i++) {                    String style1 = map.get(type[i]);                    if (!TextUtils.isEmpty(style1)) {                        str = str.replaceAll(type[i] + "\"", style1);                        str = str.replaceAll(type[i], style1);                    }                }            }            bw.write(str + "\n");        }    } catch (Exception e) {        e.printStackTrace();    } finally {        try {            if (bw != null) {                bw.close();            }            if (br != null) {                br.close();            }        } catch (Exception e) {            e.printStackTrace();        }    }}

以上,wmf的文件就可以在Android上展示了。

更多相关文章

  1. android app 缓存 ---- android 文件缓存使用流程解析
  2. Android 的广播机制和两种注册方式
  3. 阿里Android开发规范:资源文件命名与使用规范
  4. Android的几种通讯方式
  5. android进行主题切换不重启整个应用(style方式)
  6. 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)
  7. Dagger2 在 Android 项目的正确使用方式【完整篇】

随机推荐

  1. Android(安卓)键盘开发心得
  2. Android异步加载全解析之大图处理
  3. Android(安卓)Service的思考(5)
  4. Android内存泄露问题分析
  5. Android中使用DrawerLayout的注意点
  6. Android(安卓)高级UI解密 (五) :PathMeasu
  7. Android(安卓)Studio 中高德地图申请key
  8. Android手机上网、彩信APN设置
  9. Android学习笔记:活动(Activity)
  10. Android开发学习笔记:Android学习进阶路线