2012-02-20 29 views
1

在GWT中逐像素地構建畫布的執行時間非常緩慢。對於以下代碼,調用「cpa.set(...)」的2D for循環非常緩慢。GWT畫布像素操作極其緩慢

... 
RootPanel.get().add(canvas); 
context = canvas.getContext2d(); 
ImageData id = context.createImageData(canvasWidth, canvasHeight); 
CanvasPixelArray cpa = id.getData(); 

for (int y=0; y<canvasHeight; y++){ 
    for (int x=0; x<canvasWidth; x++){ 
     cpa.set(y*canvasWidth*4 + x*4 + 0,r); 
     cpa.set(y*canvasWidth*4 + x*4 + 1,g); 
     cpa.set(y*canvasWidth*4 + x*4 + 2,b); 
     cpa.set(y*canvasWidth*4 + x*4 + 3,a); 
    } 
}   
context.putImageData(id, 0, 0); 

例如,使用100x100的畫布需要10秒。我在其他一些javascript文章here中看到,在for循環中使用單獨的數組緩衝區可能更高效,然後將ImageData數組設置爲等於該緩衝區,但GWT似乎不允許使用CanvasPixelArray ,您只能在GWT中一次設置一個像素,而不是將整個像素數組緩衝區複製到CanvasPixelArray或ImageData中。

使用GWT畫布進行高效像素處理的任何想法?

謝謝。

+0

GWT的帆布相關的東西是死的簡單(CanvasPixelArray只是一個覆蓋型與什麼也沒有)。應該和在香草JS中做這個一樣快。你有沒有嘗試在香草JS相同的代碼來比較性能? – Strelok 2012-02-20 05:34:32

+0

是的,當我用JS替換像素操作循環代碼時(使用GWT的JSNI,如[這裏](http://www.onaluf.org/en/entry/13)所述),它立即加載頁面。 (由於Java版本速度非常慢,我沒有使用任何準確的方法來比較性能,GWT Java約爲10秒,GWT JSNI是即時的) – aez 2012-02-20 12:21:32

+3

您是否正在運行編譯版本?那就是說,你沒有在DevMode中運行?對於像這樣的事情,DevMode可能會非常慢。 – 2012-02-20 16:02:38

回答

1

鑑於您已將您的問題診斷爲在Devmode中運行,我將在此處詳細介紹一些解決方案。

首先,就像Strelock所評論的,Firefox中的DevMode速度更快。就我個人而言,我在Firefox中完成了所有的開發工作。

儘管如此,聽起來Devmode在開發/測試這個過程中對你來說是難以管理的。你唯一的選擇是編譯。值得慶幸的是,我們可以調整一些參數來加速它,假設你有一個體面大小的項目,將它減少到20到40秒。

給定一個主COM/foobar的/ MyApplication.gwt.xml文件像這樣:

<?xml version="1.0" encoding="UTF-8"?> 
<module rename-to="myapplication"> 
    ... 
</module> 

讓我們創建另一個COM/foobar的/ MyApplication的-Firefox.gwt.xml

<?xml version="1.0" encoding="UTF-8"?> 
<module rename-to='myapplication'> 
    <inherits name='com.foobar.MyApplication'/> 
    <!-- If you want to compile for a different browser, substitute this value. --> 
    <set-property name="user.agent" value="gecko1_8"/> 
</module> 

現在我們編譯時,一定要使用-draftCompile參數。編譯後的版本可能效率稍低一點,但編譯速度會更快。如果您使用的是默認的build.xml 文件,你可以添加其他的目標,像這樣:

<target name="gwtc-firefox" depends="javac" description="GWT compile to JavaScript (for FireFox)"> 
    <java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler"> 
    <classpath> 
     <pathelement location="src"/> 
     <path refid="project.class.path"/> 
     <pathelement location="${gwt.path}/validation-api-1.0.0.GA.jar" /> 
     <pathelement location="${gwt.path}/validation-api-1.0.0.GA-sources.jar" /> 
    </classpath> 
    <jvmarg value="-Xmx256M"/> 
    <arg line="-war"/> 
    <arg value="war"/> 
    <arg line="-draftCompile"/> 
    <arg value="com.foobar.MyApplication-Firefox"/> 
    </java> 
</target> 
+0

謝謝,我會試試看。今天我被評爲陪審團責任(美國公民義務),所以一旦我被解僱,我就會嘗試。 – aez 2012-02-21 15:55:52

+1

好吧,一切正常。事實證明,Firefox在開發模式下速度更快,並且Chrome在生產模式下快速發展,至少對於這種畫布像素操作問題而言。 – aez 2012-02-21 22:50:29