2011-06-08 19 views
3

在我的應用程序中,我推出了自己的SVG轉換器,它將原始SVG XML文件轉換爲圖形矢量對象(Paint,Path等)的序列,然後應用於畫布。首先將SVG數據與路徑列表等一起轉換爲一種字節碼格式,這意味着初始XML解析只進行一次,然後每次重繪SVG圖形都可以合理快速地進行。 SVG轉換在運行時完成的事實使我能夠在各種圖形元素上執行一些程序操作。例如,我可以在Inkscape中繪製一個圖形溫度測量表,並且在運行時,代碼會操縱測量儀的刻度並移動指針。這就是爲什麼我'需要'繪製靜態背景圖形以及使用矢量操作移動圖形,而不是編譯靜態位圖。無論如何,這是我正在做的一些背景信息;我將轉入實際問題。畫布繪製緩存位圖有點模糊或有反別名

假設一個典型的量表小部件由兩個覆蓋的視圖組成。背景視圖包含使用路徑繪製的靜態圖形(標尺的圓形面,數字圖例,刻度標記)。前景視圖包含需要經常重繪的指針圖形。每個小部件應該可能使用RelativeLayout來包含這些子視圖。

我意識到只要onDraw()被調用前景指針View,那麼onDraw就會被調用來放置在它後面的背景視圖。因此,爲了優化小部件重繪時間,我試圖使用Canvas的繪圖緩存來處理背景視圖。我所做的工作確實有效,並導致重新加速,但問題在於,我保存並稍後重繪到Canvas的緩存位圖不會像最初使用「路徑」繪製的那樣清晰。

我在後臺查看我的onDraw()方法中使用的基本代碼是:

Bitmap bm = null; 

onDraw(Canvas canvas){ 

    if(bm!=null){ 
     Paint bitmapPaint = new Paint(); 
     bitmapPaint.setAntiAlias(false); 
     bitmapPaint.setFilterBitmap(false); 
     bitmapPaint.setDither(false); 
     canvas.drawBitmap(bm, 0, 0, bitmapPaint); 

     return;    
    } 


    ... Vector drawing to the Canvas using Path objects happens here, 
     performed by the SVG converter object ... 


    setDrawingCacheEnabled(true); 
    setDrawingCacheQuality(DRAWING_CACHE_QUALITY_HIGH); 
    bm = Bitmap.createBitmap(getDrawingCache()); 
} 

,試圖得到位圖的質量有高有可能,我也做了以下幾件事:

  1. 確保高速緩存繪圖質量高。

  2. 在繪製位圖時,使用了具有抗混疊,抖動等的Paint對象(bitmapPaint)。知道位圖的任何縮放會立即影響其質量,我(希望)確保不需要執行位圖的縮放。我將View的大小設置爲原始SVG圖像的大小,這意味着我的SVG轉換器代碼不會對Canvas應用任何縮放。 scale()調用總是由SVG轉換器執行,但在目前的情況下,它是通過參數canvas.scale(1,1)創建的。如果我故意改變視圖的寬度/高度以使其與原始SVG圖像不匹配,則Canvas縮放不再是1,1,並且位圖質量的進一步損失非常明顯。

所以我的主要問題是,有沒有什麼問題我上面使用的繪圖緩存位圖使用的代碼?我有一種感覺,即使它出現在屏幕上的尺寸與我繪製的原始圖形尺寸完全相同,但我並不知道位圖發生某種密度/比例。另外(可能超出主要問題的範圍)是否有其他技術可以用來避免在前景移動圖形時重繪背景矢量圖形?據我所知,使用位圖緩存是迄今爲止我知道的唯一方法。

在此先感謝;任何意見將不勝感激。

Trev

回答

2

我很高興地說現在問題已經解決了。我意識到,首先傳遞給onDraw()的Canvas已經應用了一些縮放。這種縮放是存在的事實是降低了位圖的質量。但我不明白爲什麼Canvas應該已經有一些縮放。

我在此處發佈了另一個問題以詢問此問題:In the onDraw() method, why does the supplied Canvas already have scale?。那裏接受的答案表明我可能沒有指定android:minSdkVersion。的確,我很愚蠢,沒有。一旦我指定了minSdkVersion,緩存位圖現在繪製得很漂亮。令人驚訝的是,直到現在我還沒有意識到我正在繪製的圖像是而不是到手機的適當屏幕分辨率;由於缺少minSdkVersion,他們都被縮放。

由於adamp!

+0

感謝您發佈您的解決方案! – RichieHindle

+0

看到這個替代方法http://stackoverflow.com/questions/11560882/call-to-getdrawingcache-fails-on-api-8-everytime – Ronnie