2010-03-09 117 views
1

在J2ME中是否有任何可能將圖像(從帶有alpha的png文件加載)轉換爲新的透明灰度圖像?J2ME:將透明PNG圖像轉換爲灰度

直到現在我只有rgb值,但不是alpha。

謝謝。

編輯:是的,它應該是32位灰度。

+0

是不是灰度圖像應該只使用每個像素8位而沒有透明度的空間?你想把你的圖像變成32位灰度?您可能需要發佈顏色轉換代碼。 –

+0

也許可以提取alpha圖層並在灰度轉換後重新應用它?這似乎比逐個像素的轉換更容易。 – Nyerguds

回答

4

我發現該溶液中,這裏是代碼:

public Image getGrayScaleImage() { 
    int[] rgbData = new int[getWidth() * getHeight()]; 
    image.getRGB(rgbData, 0, getWidth(), 0, 0, getWidth(), getHeight()); 
    for (int x = 0; x < getWidth() * getHeight(); x++) { 
     rgbData[x] = getGrayScale(rgbData[x]); 
    } 
    Image grayImage = Image.createRGBImage(rgbData, getWidth(), getHeight(), true); 
    return grayImage; 
} 

private int getGrayScale(int c) { 
    int[] p = new int[4]; 
    p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level 
    p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level 
    p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level 
    p[3] = (int) (c & 0x000000FF); // Blue level 

    int nc = p[1]/3 + p[2]/3 + p[3]/3; 
    // a little bit brighter 
    nc = nc/2 + 127; 

    p[1] = nc; 
    p[2] = nc; 
    p[3] = nc; 

    int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]); 
    return gc; 
} 

的getRGB返回顏色值,該值還包括alpha通道。所以我只需要改變數組中的每個值並從中創建一個圖像。

我發現了一個有用的文檔中的諾基亞論壇:MIDP 2.0: Working with Pixels and drawRGB()

0

感謝您的代碼轉換上對灰度。但是,我注意到,在諾基亞Series 40設備上,這些代碼運行速度很慢。

有2個優化。主要的是刪除getGrayScale()中的任何對象創建。目前,每個像素都會創建一個數組對象。對於一個普通的例如QVGA,顯示76800個數組對象,這是很多垃圾,並且可能會調用GC。將int [4]定義爲類中的字段將刪除此對象創建。這裏的交易是用於該課程的少量額外的RAM。

第二種是將寬度和高度緩存到getGrayScaleImage()中。在某些設備上,方法調用getWidth()和getHeight()將被重複調用而不進行優化(JIT編譯器將會正常,但某些解釋設備不會)。所以,對於QVGA,getWidth()和getHeight()將在它們之間調用大於150000。

總之,我發現這個修改後的版本跑:-)

public Image getGrayScaleImage(Image screenshot) { 
    int width = getWidth(); 
    int height = getHeight(); 
    int screenSizeInPixels = (width * height); 

    int[] rgbData = new int[width * height]; 

    image.getRGB(rgbData, 0, width, 0, 0, width, height); 
    for (int x = 0; x < screenSizeInPixels ; x++) { 
     rgbData[x] = getGrayScale(rgbData[x]); 
    } 

    Image grayImage = Image.createRGBImage(rgbData, width, height, true); 
    return grayImage; 
} 

static int[] p = new int[4]; 
private int getGrayScale(int c) { 

    p[0] = (int) ((c & 0xFF000000) >>> 24); // Opacity level 
    p[1] = (int) ((c & 0x00FF0000) >>> 16); // Red level 
    p[2] = (int) ((c & 0x0000FF00) >>> 8); // Green level 
    p[3] = (int) (c & 0x000000FF); // Blue level 

    int nc = p[1]/3 + p[2]/3 + p[3]/3; 
    // a little bit brighter 
    nc = nc/2 + 127; 

    p[1] = nc; 
    p[2] = nc; 
    p[3] = nc; 

    int gc = (p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]); 
    return gc; 
} 

快得多(如果你真的不想使用類數據空間,只需更換INT []有四個單獨的本地INT將生活在堆棧上的變量)