2015-04-05 40 views
1

嗨我想通過tcp套接字將我的Java應用程序上的BufferedImage發送到Android設備。我目前從BufferedImage中獲取一個字節[]中的柵格,然後通過普通的OutputStream將其傳送到設備。這工作正常,我在Android端獲得相同的字節數組。但是,當我調用Bitmap.decodeByteArray()時,我只會得到空值。將Java BufferedImage發送到位圖Android

這是我必須發送我的圖片在Java中的代碼。 BufferedImage的圖像類型是TYPE_4BYTE_ABGR

byte[] imgBytes = ((DataBufferByte)msg.getImage().getData().getDataBuffer()).getData(); 

lineBytes = (String.valueOf(imgBytes.length) + '\n').getBytes();   
out.write(lineBytes); 
out.write(imgBytes); 
out.write((int)'\n'); 
out.flush(); 

我寫出來的第一件事就是圖像的大小,所以我知道有多大,使Android上的byte []。

下面是我正在嘗試用來創建Android位圖的代碼。

currLine = readLine(in); 
int imgSize = Integer.parseInt(currLine); 
byte[] imgBytes = new byte[imgSize]; 
in.read(imgBytes); 
BitmapFactory.Options imgOptions = new BitmapFactory.Options(); 
imgOptions.inPreferredConfig = Bitmap.Config.ARGB_4444; 

Bitmap img = BitmapFactory.decodeByteArray(imgBytes, 0, imgSize, imgOptions); 

字節到達罰款..他們只是不工作的位圖。

+0

您可能不想*解碼數組,因爲字節不是首先編碼的。這只是「原始」像素。您還需要傳遞高度和寬度以正確重構圖像。嘗試一下'Bitmap.createBitmap'方法。 – haraldK 2015-04-06 16:04:38

回答

2

要闡述我的意見提出的建議:

從Java /服務器端,將圖像的寬度和高度(如果你知道你的形象的類型始終是TYPE_4BYTE_ABGR你不需要其他任何東西) :

BufferedImage image = msg.getImage(); 
byte[] imgBytes = ((DataBufferByte) image.getData().getDataBuffer()).getData(); 

// Using DataOutputStream for simplicity 
DataOutputStream data = new DataOutputStream(out); 

data.writeInt(image.getWidth()); 
data.writeInt(image.getHeight()); 
data.write(imgBytes); 

data.flush(); 

現在你可以交錯ABGR字節數組包裝INT ARGB轉換在服務器端,或者在客戶端,它其實並不重要。我將展示在Android /客戶端的轉換,爲簡單:

// Read image data 
DataInputStream data = new DataInputStream(in); 
int w = data.readInt(); 
int h = data.readInt(); 
byte[] imgBytes = new byte[w * h * 4]; // 4 byte ABGR 
data.readFully(imgBytes); 

// Convert 4 byte interleaved ABGR to int packed ARGB 
int[] pixels = new int[w * h]; 
for (int i = 0; i < pixels.length; i++) { 
    int byteIndex = i * 4; 
    pixels[i] = 
      ((imgBytes[byteIndex ] & 0xFF) << 24) 
      | ((imgBytes[byteIndex + 3] & 0xFF) << 16) 
      | ((imgBytes[byteIndex + 2] & 0xFF) << 8) 
      | (imgBytes[byteIndex + 1] & 0xFF); 
} 

// Finally, create bitmap from packed int ARGB, using ARGB_8888 
Bitmap bitmap = Bitmap.createBitmap(pixels, w, h, Bitmap.Config.ARGB_8888); 

如果你真的想ARGB_4444,你可以轉換的位圖,但要注意,不斷在所有最新版本的Android API的棄用。

+0

謝謝你的回答,它清除了我一直困惑的一些事情。從整體上來看,這個效果更好。不幸的是,由此產生的圖像根本不起作用。所有的顏色都完全關閉。我可以看到圖像中產生的形狀,但我不認爲這些輪班工作正常,雖然我畫了一些東西,它絕對看起來應該是正確的。 – 2015-04-06 23:32:43

+0

通過將像素for循環中的索引更改爲imgBytes [(i * 4)]爲所有索引,我將它用於紅色和綠色,因爲我們需要在像素[1]上獲取字節4-7,而不是1-4。但是每當我用藍色拍攝一張照片時,它會完全損壞爲黃色。我正在對字節值進行一些手動調試,但沒有發現太多 – 2015-04-07 00:17:52

+1

確定它現在正在工作我剛纔意識到必須通過在每個字節上使用&0xFF來壓縮我們所有的字節到8個有效位。所以像素的最終循環語句[i] =((imgBytes [byteIndex]&0xFF)<< 24)| ((imgBytes [byteIndex + 3]&0xFF)<< 16)| ((imgBytes [byteIndex + 2]&0xFF)<< 8)| (imgBytes [byteIndex + 1]&0xFF); 這完美的作品!非常感謝。 – 2015-04-07 00:29:16

0

imgSize應該是圖像的大小。爲什麼不試試imgBytes.length

相關問題