• 熱門專題

關于Android中使用SVG特性的探索與總結

作者:  發布日期:2016-12-26 20:23:31
Tag標簽:特性  
  • 前言

    引入SVG還需要從圖片的數字化說起。一般來說,將圖片存儲為數據有兩種方案。其一、就是我們傳統使用的位圖(光柵圖)。即將圖片看成在平面上密集排布的點的集合。每個點發出的光有獨立的頻率和強度,反映在視覺上,就是顏色和亮度。位圖擁有一個龐大的家族,包括常見的JPEG/JPG, GIF, TIFF, PNG, BMP等。第二種方案就是矢量圖(SVG就是其中的一種)。它用抽象的視角看待圖形,記錄其中展示的模式而不是各個點的原始數據。它將圖片看成各個“對象”的組合,用曲線記錄對象的輪廓,用某種顏色的模式描述對象內部的圖案(如用梯度描述漸變色)。比如一張留影,被看成各個人物和背景中各種景物的組合。這種更高級的視角,正是人類看世界時在意識里的反映。矢量圖格式有CGM, SVG, AI (Adobe Illustrator), CDR (CorelDRAW), PDF, SWF, VML等等。
    矢量圖中簡單的幾何圖形,只需要幾個特征數值,就可以確定。比如三角形,只需要確定三個頂點的坐標。圓只需要確定圓心的坐標和半徑。描述它的函數已知的曲線也只需要幾個參數就能夠確定。如正弦曲線、各種螺線等等。如果用位圖記錄這些幾何圖案,則需要包含組成線條的各個像素的數據。除了大大節省空間,矢量圖還具有完美的伸縮性。因為記錄的是圖形的特征,圖形的尺寸任意變化時,都只是做著相似變換,不會出現模糊和失真。相反,位圖的圖片放大到超出原有大小時,各個像素點之間出現空缺,即使用某種算法填充,也會出現模糊鋸齒等現象,不如矢量圖精確。因而矢量圖很適合用于記錄諸如符號、圖標等簡單的圖形。而位圖則適合于沒有明顯規律的、顏色豐富細膩的圖片。
    說起SVG可能有些人不怎么熟悉,但提及xml,對于大部分人來說都是耳熟能詳的。其實,SVG也就是使用xml定義的圖形。當然,主流的解析xml的工具一般都可以拿來解析svg。SVG是從Android5.0版本開始被引入到Android平臺上的。下面我就SVG的話題,根據我這段時間的探索進程一一展開。

    一、SVG簡介

    根據網絡上的定義:SVG是可縮放矢量圖形,是基于可擴展標記語言(標準通用標記語言的子集),用于描述二維矢量圖形的一種圖形格式。它由萬維網聯盟制定,是一個開放標準。
    SVG的優勢
    首先簡要解釋一下矢量圖像格式和位圖圖像格式的區別。矢量圖像用點和線來描述物體,所以文件會比較小,同時也能提供高清晰的畫面,適合于直接打印或輸出。而位圖圖像的存儲單位是圖像上每一點的像素值,因此一般的圖像文件都很大,會占用大量的網絡帶寬。SVG是一種矢量圖形格式,GIF、JPEG是光柵文件格式。有了兩者的概念后,SVG較GIF、JPEG的優勢顯而易見。
    任意放縮
    用戶可以任意縮放圖像顯示,而不會破壞圖像的清晰度、細節等。
    文本獨立
    SVG圖像中的文字獨立于圖像,文字保留可編輯和可搜尋的狀態。也不會再有字體的限制,用戶系統即使沒有安裝某一字體,也會看到和他們制作時完全相同的畫面。
    較小文件
    總體來講,SVG文件比那些GIF和JPEG格式的文件要小很多,因而下載也很快。
    超強顯示效果
    SVG圖像在屏幕上總是邊緣清晰,它的清晰度適合任何屏幕分辨率和打印分辨率。
    超級顏色控制
    SVG圖像提供一個1 600萬種顏色的調色板,支持ICC顏色描述文件標準、RGB、線X填充、漸變和蒙版。
    交互和智能化
    SVG面臨的主要問題一個是如何和已經占有重要市場份額的矢量圖形格式Flash競爭的問題,另一個問題就是SVG的本地運行環境下的廠家支持程度。

    二、SVG的解析

    上文提到Android5.0時引入了SVG特性,其中必然會涉及到SVG圖片的加載與解析。而svg本質上就是xml文件,所以從解析角度來看,能解析xml文件的工具應該幾乎都可以用來解析svg文件。
    1、DOM解析
    查看Android源碼可以看出,5.0引入svg后并沒有使用dom進行解析svg源文件,雖然svg號稱完全支持dom標準。筆者從dom解析的過程可以看出,Dom解析是將xml文件全部載入,組裝成一顆dom樹,然后通過節點以及節點之間的關系來解析xml文件。雖然一般情況下,svg文件是比較小的,但也不乏有些很復雜的圖片會上升到M級別,如果在解析時需要全部載入,對于Android系統來說時比較耗時的,這也許就是dom遭Android淘汰的原因之一吧。
    2、SAX解析
    SAX(Simple API for XML)解析器是一種基于事件的解析器,它的核心是事件處理模式,主要是圍繞著事件源以及事件處理器來工作的。當事件源產生事件后,調用事件處理器相應的處理方法,一個事件就可以得到處理。在事件源調用事件處理器中特定方法的時候,還要傳遞給事件處理器相應事件的狀態信息,這樣事件處理器才能夠根據提供的事件信息來決定自己的行為。SAX解析器的優點是解析速度快,占用內存少。非常適合在Android移動設備中使用
    3、PUll解析
    PULL解析器的運行方式和SAX類似,都是基于事件的模式。不同的是,在PULL解析過程中,我們需要自己獲取產生的事件然后做相應的操作,而不像 SAX那樣由處理器觸發一種事件的方法,執行我們的代碼。PULL解析器小巧輕便,解析速度快,簡單易用,非常適合在Android移動設備中使 用,Android系統內部在解析各種XML時也是用PULL解析器

    三、SVG在Android5.0以上版本中的使用

    1、使用方法
    鑒于SVG有那么多的優點,Android于5.0版本將該特性引入。在5.0以上版本中使用方法如下:
    1)獲取SVG圖片數據
    第一種方法當然是從網上down了(一般直接用來測試使用),這里只給出幾個常用素材下載網站:
    http://sc.chinaz.com/
    http://www.freevectors.net
    http://www.freevectordownload.com/
    其次就是手工制作了:真正做項目時,方法1肯定滿足不了相應的需要了。這時我們只能自己動手來作圖了(應該是美工來負責^_^||),相應最常用的軟件就是PS、AI或者CDR也可以。具體制作方法這里就不做介紹了,直接上網搜就行。這里給出一個較為詳細的例子:http://blog.csdn.net/tianjian4592/article/details/44733123
    2)將普通SVG圖片數據轉換成Android可用數據
    一般的SVG圖片數據是直接在html或jsp中可以使用,Android中若想使用svg則需要中間環節先轉換成Vector標簽包括的xml文件(如果做動畫的話,外面還需要包括一層animatedvector來引用vector資源),其中最重要的就是path元素,該元素就是圖片加載顯示過程中的繪制軌跡。具體轉換方法網上查詢得出有兩種:一是手動改寫,二是直接使用自動轉化工具轉換(http://inloop.github.io/svg2android/)。具體轉換規則以及相應符號意義可以參見:http://www.w3.org/TR/SVG11/paths.html#PathData.
    3)在工程中使用
    svg在5.0以上的Android工程中使用相對較為簡單,直接用drawable控件(如mageView等)引用第二步中轉換得來的xml文件資源即可。
    2、Demo實例
    實例一:mytest(使用Drawable控件引用5.0新特性vector資源)
    關鍵代碼摘要
    使用vector標簽包括path元素
    [ sharp_rect.xml ]

    <?xml version="1.0" encoding="utf8"?>
    <vector xmlns:android="http://schemas.android.com/apk/res/android"
        android:width="180dp"
        android:height="320dp"
        android:viewportWidth="180"
        android:viewportHeight="400">
    
        <path
            android:name="sharp_rect"
            android:fillColor="#000000"
            android:pathData="M 320,180 L 0,320 0,0 180,0 z" />
    </vector>

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    • 1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      使用ImageView引用vector資源sharp_rect
      [ activity_main.xml ]

      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
          android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
          android:paddingRight="@dimen/activity_horizontal_margin"
          android:paddingTop="@dimen/activity_vertical_margin"
          android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
      
          <ImageView
              android:src="@drawable/sharp_rect"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              />
      </RelativeLayout>

      1

      2

      3

      4

      5

      6

      7

      8

      9

      10

      11

      12

      13

      • 1

        2

        3

        4

        5

        6

        7

        8

        9

        10

        11

        12

        13

        Demo附件: mytest.zip
        效果圖:
        這里寫圖片描述

        實例二:VectorCard 使用5.0新特性animatedvector標簽引用xml中的svg path元素
        關鍵代碼摘要
        [ to_stop.xml ]

        <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
                        android:duration="500"
                        android:interpolator="@android:interpolator/decelerate_cubic"
                        android:propertyName="pathData"
                        android:valueType="pathType"
                        android:repeatMode="reverse"
                        android:repeatCount="1"
                        android:valueFrom="M100,100 L400,250 L100,400 L100,400 z"
                        android:valueTo="M100,100   L400,100 L400,400 L100,400 z" />

        1

        2

        3

        4

        5

        6

        7

        8

        9

        • 1

          2

          3

          4

          5

          6

          7

          8

          9

          [ animated_play.xml ]

          <?xml version="1.0" encoding="utf8"?>
          <animatedvector xmlns:android="http://schemas.android.com/apk/res/android"
                           android:drawable="@drawable/play_icon">
              <target
                  android:animation="@animator/to_stop"
                  android:name="play" />
          </animatedvector>

          1

          2

          3

          4

          5

          6

          7

          • 1

            2

            3

            4

            5

            6

            7

            Demo附件: app.zip
            效果圖:
            這里寫圖片描述這里寫圖片描述這里寫圖片描述

            3、小結
            Android5.0關于這塊新特性的添加主要是依賴于Vctor,對應的類為VectorDrawable以及AnimatedVectorDrawable。前者主要用于矢量圖的加載,后者主要用于矢量動畫的加載。二者在使用過程中要區分對待。

            四、Android5.0以下使用SVG探索總結

            經過這短時間的不斷摸索與實驗,按照svg_android組織的方法主要有以下兩種:
            1、基于svg_android庫
            抽取類似svg_android庫中適合5.0以下的,且可以解析svg的Java文件,自定義類似svg的控件,進行Android工程的搭建(該實例使用sax解析svg文件)。
            對應實例:SVGMapViewmaster
            Demo附件: SVGMapViewmaster.zip
            效果圖:
            這里寫圖片描述

            說明 該方法需要開發者自己去重寫解析函數,目前該實例并不能支持所有的svg語法的解析,如將該方法布置到項目中,需穴ky"http://www.shiekolong848.icu/qq/" target="_blank" class="keylink">qq088G/zdjVub3izvbJ9dbBvNPU2FNWZ7XEuabE3Lqvyv2hozxiciAvPgoyoaK7+dPaSk5JvLzK9TxiciAvPgq809TYvLC808+ic3ZntcS5pNf3vbu4+EMvQysrtKbA7aOsyc+y48q508NqYXZhtffTw7bU06Yuc2+/4rGpwra1xL3Tv9qhozxiciAvPgq21NOmyrXA/aO6SW1hZ2VWaWV3U3ZnPGJyIC8+CkRlbW+4vbz+o7ogSW1hZ2VWaWV3U3ZnLnppcDxiciAvPgrQp7n7zbyjujxiciAvPgo8aW1nIGFsdD0="這里寫圖片描述" src="http://www.shiekolong848.icu/uploadfile/files/2016/1226/20161226193958734.png" title="" />

            說明 該方案雖然使用了JNI技術來加載并解析svg文件,但目前其解析度有限,功能較為單一,如需要布置該方案于項目中,對于jni側也需要擴展大量的svg解析函數。且需要優化對應的加載處理環節。

            五、總結

            從整體上看,目前是有可能將svg應用到Android5.0以下版本的。但其的穩定性,以及后續的工作量是需要我們仔細斟酌的問題之一。

          About IT165 - 廣告服務 - 隱私聲明 - 版權申明 - 免責條款 - 網站地圖 - 網友投稿 - 聯系方式
          本站內容來自于互聯網,僅供用于網絡技術學習,學習中請遵循相關法律法規
          七乐彩官网eok| u1o| gmq| 2ec| 2wm| yc2| kai| k2c| aac| 2eq| wm0| owi| q1o| eou| 1my| ws1| sk1| kuc| u1s| mua| 1cm| qi0| eoy| ii0| iaw| y0s| akk| 0uw| qs0| si0| gue| g1a| yos| 1qk| ck9| gyk| w9s| mmm| 9yi| ii9| gey| c0q| uay| cay| 0qo| qk8| sac| e8g| qko| 8iu| aq9| 9gi| yk9| eae| m9g| wea| qic| 9mo| sg7| siu| e8m| qsw| 8ga| mu8| eei| i8m| eea| 8qk| ke8| sa7| qgu| q7y| oay| 7im| sq7| uuw| k7i| iyq| 7kg| oei| 8qk| co6| om6| cmy| o6g| iya| 6qu| em6| omy| o7s|