2014-01-15 89 views
0

我將RGBA圖像轉換爲RGB。使用幼稚陣列副本:Array複製排除每個x元素

for (int j=0, i=0; i<argbBytes.length; i++){ 
    if (i%4 < 3) { 
     thumbRGB888[j++] = argbBytes[i]; 
    } 
} 

但是,正如預期的,它是超慢(相比於System.arraycopy()方法),特別是在Android設備上。有沒有更快速度的技巧?

+0

ü可以試試我+ 4還是別的什麼,而不是我++ – Manmohan

+0

@Manmohan我繞過只有一格。 – Mark

+0

System.arraycopy()然後設置每個第四個元素爲0應該給出相同的結果,但也許更快? – neurite

回答

2

使用兩個指標和System.arraycopy(),每次複製3個要素:

for (int i = 0, j = 0; i < argbBytes.length; i += 4, j += 3) 
{ 
    System.arraycopy(argbBytes, i, thumbRGB888, j, 3); 
} 

應該是顯著更快。它不僅可以擺脫模和比較,System.arraycopy()是用本機代碼實現的,依賴memcpy這將比個人分配更快。

+0

出於好奇,我在C#中運行代碼,當然,我將'System.arraycopy'更改爲'Array.Copy'。然後時間比原來長兩倍(6091ms與3021ms相比)。也許在C#中'Array.Copy'的實現不同於Java中的'System.arraycopy'。我錯了嗎? – vutran

+0

坦率地說,C#和Java沒有任何關係,所以我很困惑與什麼有關。如上所述,是的,這是在JVM中的本地代碼中實現的,並且比逐個處理元素要快得多。 –

+0

是的! 45ms與80ms – Mark

0

而不是

if (i%4 < 3) 

for (int j=0, i=0; i<argbBytes.length; i++){ 
    thumbRGB888[j++] = argbBytes[i++]; 
    thumbRGB888[j++] = argbBytes[i++]; 
    thumbRGB888[j++] = argbBytes[i++]; 
} 

這個解決方案是遠遠快,因爲模運算和比較更costfull。

0

您應該避免if聲明,它有2個操作。
從i = 0開始,i%4表示:0,1,2,4,5,6,8,9,10。 以下是我會怎麼做:

int div = 4; 
int n = argbBytes.length - argbBytes.length%div; 
int i=0; 
int j=0; 

for (; i<n; i+=div){ 
    // i = 0, 4, 8 ... then i, i+1,i+2 should pass (i%4<3) 
    thumbRGB888[j++] = argbBytes[i]; 
    thumbRGB888[j++] = argbBytes[i+1]; 
    thumbRGB888[j++] = argbBytes[i+2]; 
} 

for(;i<argbBytes.length;i++){ 
    //i=n,n+1,n+2, since n%4==0 then (i%4<3) is passed 
    thumbRGB888[j++] = argbBytes[i]; 
} 

- >的i增量相同
與測試[0,1,2,3,4,5,6,7,8,9,10]返回[0,1,2,4,5,6,8,9,10] 測試與10,000,000元件的陣列,在30
原始代碼的循環運行:3191ms
修改後的代碼:1653ms
I」我用C#測試過,所以結果可能會有所不同。順便說一句,這可能不是一個很大的改進。

0

沒有一個明確的答案,但有指針​​: 從來沒有這樣做過,並不能完全滿足你的要求,但留下轉化爲BitmapFactory。完全不確定,但是:

使用BitmapFactory從字節中獲取ARGB位圖。如果不可變,那麼可能不會有新的分配完成。也可能是,你首先需要將這些字節包裝到一個Buffer中。

然後Bitmap.copy應該是可能的左右。

有些瘋狂的想法:

BitmapFactory.Options opts = new BitmapFactory.Options(); 
opts.inMutable = true; // Bitmap generated mutable. 
opts.inPreferredConfig = Bitmap.Config.ARGB_8888; // I hope not BGRA. 
Bitmap bmARGB = BitmapFactory.decodeByteArray(argbBytes, 0, argbBytes.length, 
    opts); 

bmARGB.setHasAlpha(false); 

DisplayMetrics display = ...; 
int[] colors = null; // Palette 
Bitmap bmRGB = bmARBG.createBitmap(display, colors, width, height, 
    Bitmap.Config.RGB_565); // 16 bit colors only! 
bmARGB.recycle(); 
+0

AFAIK,BitmapFactory沒有RGB888圖片文件。順便說一句,我已經使用BitmapFactory創建了原始的RGBA。 – Mark