2015-04-05 85 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

相关问题