2012-08-08 90 views
3

我有一個對應於「灰度位圖」(一個字節 - >一個像素)的字節數組,我需要爲此圖像創建一個PNG文件。在Android中的灰度位圖

下面的方法工作,但創建的PNG是巨大的,因爲我使用的位圖是一個ARGB_8888位圖,每個像素需要4個字節,而不是1個字節。

我還沒有能夠使其與其他Bitmap.Config不同於ARGB_8888。也許ALPHA_8是我需要的,但我一直無法使它工作。

我也嘗試了一些其他帖子(Convert a Bitmap to GrayScale in Android)中包含的toGrayScale方法,但是我的大小與問題相同。

public static boolean createPNGFromGrayScaledBytes(ByteBuffer grayBytes, int width, 
     int height,File pngFile) throws IOException{ 

    if (grayBytes.remaining()!=width*height){ 
     Logger.error(Tag, "Unexpected error: size mismatch [remaining:"+grayBytes.remaining()+"][width:"+width+"][height:"+height+"]", null); 
     return false; 
    } 
    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
    // for each byte, I set it in three color channels. 
    int gray,color; 
    int x=0,y=0;   
    while(grayBytes.remaining()>0){ 

     gray = grayBytes.get(); 
     // integer may be negative as byte is signed. make them positive. 
     if (gray<0){gray+=256;} 

     // for each byte, I set it in three color channels. 
     color= Color.argb(-1, gray, gray, gray); 


     bitmap.setPixel(x, y, color); 
     x++; 
     if (x==width){ 
      x=0; 
      y++; 
     }   
    } 
    FileOutputStream fos=null; 

    fos = new FileOutputStream(pngFile); 
    boolean result= bitmap.compress(Bitmap.CompressFormat.PNG,100,fos); 
    fos.close(); 
    return result; 
}  

編輯:鏈接到生成的文件(它可能看起來是無稽之談,但只是與randon數據創建)。 http://www.tempfiles.net/download/201208/256402/huge_png.html

任何幫助將不勝感激。

+0

定義「巨大」。我的圖像編輯程序創建了一個RGB PNG,其透明度比灰度PNG大40%,考慮到它的數據量增加了300%,這個效果並不差。 – 2012-08-09 02:47:18

+0

原始灰度png是1732K。用上述過程創建的png是5445K – richardtz 2012-08-09 07:36:52

+0

哇,這聽起來像是PNG壓縮器中的一個bug。如果將5445K的結果通過其中一個PNG壓縮機運行,結果有多大?你可以將文件發佈到某個地方嗎? – 2012-08-09 13:30:34

回答

4

正如您已經注意到的那樣,將RGB圖像保存爲灰度圖像非常昂貴。如果您有亮度數據,那麼最好保存爲灰度PNG而不是RGB PNG。

Android Framework中提供的位圖和圖像功能確實適用於讀取和編寫由框架和UI組件支持的圖像格式。灰度PNG不包括在這裏。

如果你想節省了Android上的一個灰度PNG,那麼你就需要如果您使用OpenCV進行Android的圖書​​館使用圖書館像http://code.google.com/p/pngj/

+0

我會嘗試你建議的圖書館。我覺得奇怪的是,它不能用Android Framework來完成。謝謝! – richardtz 2012-08-09 07:47:15

+0

它可以在普通的舊Java中完成,但Android缺少所需的類。在手機上保存亮度圖像是非常罕見的事情。 – 2012-08-09 07:50:19

+0

我很擔心,因爲圖像將通過電子郵件發送。但我同意這不是手機的常見用例。 – richardtz 2012-08-09 12:16:50

2

,您可以使用庫來保存二進制數據到PNG文件。 我的辦法是:在JNI部分 , 集墊,其數據開始與字節數組:

jbyte* _ByteArray_BrightnessImgForOCR = env->GetByteArrayElements(ByteArray_BrightnessImgForOCR, 0); 
Mat img(ByteArray_BrightnessImgForOCR_h, ByteArray_BrightnessImgForOCR_w, CV_8UC1, (unsigned char *) _ByteArray_BrightnessImgForOCR); 

然後把它寫入PNG文件。

imwrite("/mnt/sdcard/binaryImg_forOCR.png", img); 

當然,您需要一些時間才能熟悉OpenCV和Java本機編碼。繼OpenCV for Android examples後,學習速度很快。