I'm trying implement a simple file transfering app.
My app does like that:
1. Capture current camera preview in Android
2. Send it to Javafx application via Bluetooth
3. When Javafx app received the image saving it and show on the window
4. After some drawing over the image capture it then send it to Android again
I implemented like this on Android side first
I created a kind of packet which contains file size, actual data and eof.
ByteArrayOutputStream baos = new ByteArrayOutputStream();
data.compress(Bitmap.CompressFormat.JPEG, 100, baos);
// filesize + data + end of file
String fileSize = String.valueOf(baos.size());
fileSize += '\0'; // end of the filesize string
String eof = "eof"; // end of packet
// set packet size
int packetSize = fileSize.length() + baos.size() + eof.length();
ByteBuffer byteBuffer = ByteBuffer.allocate(packetSize);
byteBuffer.put(fileSize.getBytes());
byteBuffer.put(baos.toByteArray());
byteBuffer.put(eof.getBytes());
byte[] data = new byte[byteBuffer.capacity()];
byteBuffer.position(0);
byteBuffer.get(data);
and send the data to bluetooth outputstream socket
On JavaFX side,
bytes = btIn.read(buffer);
// receive packet data
if (fileSize == null) {
for (int i = 0; i < bytes; i++) {
if (buffer[i] == '\0') {
fileSize = new String(buffer, 0, i);
break;
}
}
}
// eof offset
int offset = bytes - 3;
byte[] eofByte = new byte[3];
eofByte = Arrays.copyOfRange(buffer, offset, bytes);
String message = new String(eofByte, 0, 3);
if (message.equals("eof")) {
eof = true;
fos.write(buffer, 0, bytes-3);
} else {
// set buffer size to file size
if (fileBuffer == null) {
fileBuffer = ByteBuffer.allocate(Integer.parseInt(fileSize));
fileBuffer.put(buffer, fileSize.length()+1, bytes);
fos.write(buffer, fileSize.length()+1, bytes);
} else {
fileBuffer.put(buffer, 0, bytes);
fos.write(buffer, 0, bytes);
// for progress bar
percent = (float) fileBuffer.position() / (float) fileBuffer.capacity();
}
}
log(String.valueOf(percent));
if (eof) {
byte[] data = new byte[fileBuffer.capacity()];
fileBuffer.position(0);
fileBuffer.get(data);
ByteArrayInputStream input = new ByteArrayInputStream(data);
bufferedImage = ImageIO.read(input);
image = SwingFXUtils.toFXImage(bufferedImage, null);
if (bufferedImage != null) {
log("got the image");
}
// set null fileBuffer and fileSize for next images
fileSize = null;
fileBuffer = null;
}
}
above code is for receving image from the Anroid
and Sending part on JavaFX is:
WritableImage writableImage = new WritableImage((int)canvas.getWidth(), (int)canvas.getHeight());
canvas.snapshot(null, writableImage);
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(writableImage, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ImageIO.write(bufferedImage, "jpg", baos);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
byte[] imageInBytes = baos.toByteArray();
log(String.valueOf(imageInBytes.length));
bct.write(imageInBytes);
String eof = "end of file";
byte[] eofbyte = eof.getBytes();
bct.write(eofbyte);
the sending and receiving part work fine..
But I have problems on result images
This is JavaFX side when received the image from Android and ss you see, the most left side of the image is not desired
and more weired after receving image from JavaFX side the result image on Android like this:
My question is how should I fix the code to get correct images?
I think you were hit by this bug:
https://bugs.openjdk.java.net/browse/JDK-8041459
You can avoid this problem by using PNG instead of JPG. Another option is to explicitly convert the image into an image without alpha component before storing it.
Michael
Related
The code right down to this saving photos from a HTML page is working.
String
nameimage,
srcfoto;
nameimage = vs.getValor("NAMEIMAGE");
srcfoto = vs.getValor("img").toString();
URL url = new URL(srcfoto);
InputStream in = new BufferedInputStream(url.openStream());
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buf = new byte[1024];
int n = 0;
while (-1 != (n = in.read(buf))) {
out.write(buf, 0, n);
}
out.close();
in.close();
byte[] response = out.toByteArray();
FileOutputStream fos = new FileOutputStream("C:\\img\\ " + nameimage + ".png");
fos.write(response);
fos.close();
vs.setReturnOK("Image save!");
return vs.getReturnOK();
My problem is that I need to download the following canvas src..
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfQAAABkCAYAAABwx8J9AAAeKElEQVR4Xu2de+h2S1XHNfqvLLCLlZW/MjAyTyiR1Sk5kHTT7hfs/hJRpySlLEvKhILSPJ0g0mNF9RbdMel+kcwjncIEuxsJnfqJ3ROR6vSHRLU+x2fZas7sPWv2nv1c9vt9YPE+7++ZmT3zXWvmO7NmzeyHP0wfISAEhIAQEAJC4OIRePjFt0ANEAJCQAgIASEgBB4mQpcRCAEhIASEgBDYAQIi9B0oUU0QAkJACAgBISBClw0IASEgBISAENgBAiL0HShRTRACQkAICAEhIEKXDQgBISAEhIAQ2AECIvQdKFFNEAJCQAgIASEgQpcNCAEhIASEgBDYAQIi9B0oUU0QAkJACAgBISBClw0IASEgBISAENgBAiL0HShRTRACQkAICAEhIEKXDQgBISAEhIAQ2AECIvQdKFFNEAJCQAgIASEgQpcNCAEhIASEgBDYAQIi9B0oUU0QAkJACAgBISBClw0IASEgBISAENgBAiL0HShRTRACQkAICAEhIEKXDQgBISAEhIAQ2AECIvQdKFFNEAJCQAgIASEgQpcNCAEhIASEgBDYAQIi9B0oUU0QAkJACAgBISBClw0IASEgBISAENgBAiL0HSjxAprwOVbHVyys579YvqeYvHFh/p5sT7LEr5/J8Cb77fEmD/QUqrRCQAgIgWMgsFdCjwSyZBB+VwP/PpMnH5TwVfbvjx6+l7+N0lNJXDUSfKo97FWdD6yV80Ir43kT5azFrlbsORP6u1iFX2JyZyeuS+yq8xFKfiYIHKvPn0lzZ6tR9pc4Nl5C/XddRxF6Xb3nSui/YNX9MpO3J61yaiASob8DwNaKPAOzBrQMSpedRoT+f/oToZ+xLYvQL4vQqW3PKn2KsE5J6L2Tkq26z5TXYA7f51hl7ioqJELfSkPnU64IXYR+PtY4UxMRej+hZxUbB/8lJDZFONmy5lzJtzqh1yY6PROlR5sRsPXxOBMRerZH7D/d2j5/CQhphX7GWhKhXwahv9iq+QgT3+fNkE8krTL/rUzotdVWBs+apTDpeqSJx1eccVdX1Y6AgAj9CCDrEdMIiNAvg9Ah4NeZeKR4a5UeZ9EE291h8qwwIbiVCb30fGy5wq656EuLWzqZKMupeXSOeUJgbpzdEoe5OIhjBy6OJvQ5V/8ou+nlR63QexE7YnoR+uUQ+vOtqh553xqoo0sY8v42kxjJfasSejlAtiZGS7vikmC7zAAdCcN1mDlBMKXvcnDuxaNFYFvhgF4y7Y76m7P5pXou87XwyD6nZ89+ym7KSVS2/XHsoL5uE/8dxp9sOzI2nS1L6RIIiNAvh9A5ZhYHsbkOGjsznerVIvQHFV0SzFar8yVERv1a9Yl6vdvS327iRytb3X2q7FjX1kQxPqMc+GuD9zFwaLXbf88SWra8WroRhL4Esxr2tRiaFsHOTXh7JhmOTet5a7BW3goCIvTLIvTYqaYG3zjQ+uz6v0ToDyo6Drg95NU7ePig3FrxloN3q05Truuaa7kk3Kmyy4G6NalwLDL3FWyBQ4nZlFu9JLRLIPRSZ2CdmShNYVDqtrUFEe2rTCtC7x0FTpBehH5ZhE5tW6v0cnVONHbP4JYZqHtNNesebQ04vc+N6de6l9c8ey5vD6GWhN7CqySIKbLu1fkW+6hZHJasgpkEfIHJ1GVKo3S7pG7+7F77zOJVToCmJplZT80Wuh+F/y1fzq1A6COUnF21xGet6dxzxB0H6XLVFTt57LiXQuiOX2ulukSn5QB4jBVbtp61vfFa3my6KZKYanPGfR7rM2eD2TYvad+5k8maPh8JtTVRc+xinjlvUCsQNDvx47nnroM19nfxeUXoORWeE6FT46mBPXbc6Kq7NEJ3rSzBfUqj50zoUW9zA3MvoZe2MlV2j32Uk83WtkKuh70jVQuH7Kq055kj064h9Jg3a/fZiVWp3zhh7tW9CH2kxQwuS4SeAzTbwY6xQucZtY58v/39PhOCpMoZfk+n7XW/ZhCkzJeZzL1kpRYMNHKlfg6Entl6GE3oLZKsrfbmVogljksCn5biMEdMGTvcOs1SQi+PmWZfRpSJqfE2TwW8Pc0S+HHYjGdAhL61Fa0o/1Yg9IyRlhCOWAks7dxel569ciYcbw0ds5yAnJrQe0y0HOxHrQBPQei1IKcWFqci9KzNL3ENj8RhyZW9LcxH/b60zy8JOKvVuTW5mougz06eReijrGWDckTodVCzg9ucSpZ27iyhl0Esr7GMBP7UJjCXROhbrcKOSehL3+CG7k9F6Dw7Y7M9bv8tcMiWuWQiv3aIzeBXe8aSCc8SQifP2gmRCH2tlWyYX4R+uYQ+NbDVtgcuidDRSLmSaK08Ml2kN4o4U2YtzRzhTJFM1i3eQ6a1iWHL29Hak+1x8W6JQzn5aOlqhP20npGdEJ2a0Gt66QkQFaFnLOFEaUTol0voNeIbcSZ3iz30XvPujbrOln+Mc+jlCiizUjwXQm8N1tmo6tpKcCQOUd/Z1e2SOJisXXm6ESv0rOu7t24xfXn8sTXRi3lbNrKmXsq7EgER+mUTenblnU1XDsSZQXilCVazb0XoW98UV+Kcxe9cCH1O/z0D+dY4tGyu5lbO6qJV9tzvIwid8rf0KEy53LOr9B47WIOl8i5AQIR+2YQeV+lzM/tLI/QtXO5gNRXp+/YFfaeWZWnsxTkR+lQUe5xktchxaxyy6irJa0uipE5LCX0pXlkcPF0Zd3OP/fCCUEgGHxF6L+pHTC9Cv3xCz5jLpRF6HIhHuyBLd+NIV+zSI13nROglMdVeAtNazW2NQ8bmaxO4kbqu1WEpoa+ZDKzB4sctc3xpU6avidCziJ8gnQhdhF4icOo99K1X0dn7sjPdkRXPE038fehLV1rnRujl0bTbrI0vMrnzAEprJbc1Dhnd1Ai9Ve9suVPp1hD6lttBcwGhvf2tZ3GwFk/l70RAhC5C35rQGeTeFkhvzkRrEbhbDMK1fcSe1VscBGO+3kj6WntPeWzNdVPW6+fsh2ccfswEUG2FA7i/0uQzTB5IjHXZ+8kTRaWSrCH0NbbfwqU1Se+dTMy9xCUFlBJtg4AIXYR+DEK/KzxkiqBrl160XLtrekXpevey5oi9lqdMn41yn3r+ORA6WEwFT2UnPlvg0LOaLJ+/pS257awhdMqoeY/m4hUyxJqNRyntcW4i3Xrhi09OXm5t4uVQ+hwJARG6CH2O0JeYYTkATRFXq+zMSrBVRuv3zBWkrTJKgstefOLlsm8Zg5POhdBr5JLZY/V2bYFDSegt3fjvrSC+bDmtdGsJnfKXvA+dfLU2lnjNTWrKtD3X/07hsoV3raWDW/p3EboI/RwJPbsKHNF5l5LEHPFmyawWcHYuhA625WSsd5U7GoclujrGxNDtcAShU9aSdpa66d324LnlJG4Ou8z5fxH6iBGqowwRugh9a0KP5bdW66ceAFor9l5ymBr0ysH33ILiXGdZd21ryBmNQ4b0eicfrTZkfh9F6Nk+k317Xo9npfddCku2jjJYKs0CBPZK6AugUBYhIASEgBAQApeLgAj9cnWnmgsBISAEhIAQeCcCInQZgxAQAkJACAiBHSAgQt+BEtUEISAEhIAQEAIidNmAEBACQkAICIEdICBC34ES1QQhIASEgBAQAiJ02YAQEAJCQAgIgR0gIELfgRLVBCEgBISAEBACInTZgBAQAkJACAiBHSAgQt+BEtUEISAEhIAQEAIidNmAEBACQkAICIEdICBC34ES1QQhIASEgBAQAiJ02YAQEAJCQAgIgR0gsEdC/0jTy21BN39m3/+iU1dzZZS/dRb9kOSxflNl/7PlelXHg6bKqWExAq9a1ZbgtERXWVjexxJ+iMmHHTL8k/0LrryJ6l+zhSjd2SKwxN7mGrOlLY4GEduWDY9G9QLL2yOhf4np4ckmfxj+/elO3cyVEX/rLPYhyb2eXr+psr/Ycj6t42E/YGnfbPIPIU/5LP9pBF61qn3z4Y+xDnNNmKpfR7MfkvTd7C+fZQJ+2PofmfzVIdUH2L8fZPIJJr9mwqsoeyd+a+qmvGMR2LJfjq3puNKurKhvMHmdSe8YN64WKulsENgroQMwBk4n9+89oMd8ZRlLy6w9P1v2r1vmZ5pcJxoBif2HSanbqXrPtTXxuMkkPXWmkJG4Ut4nmbzI5OdNbppMrWDA62NNvtHk9Yc8D6xpuPKeBIGR9jOyrC3A8InqN1nh95mweBGhb4H0hZUpQq8rrEXoH3PoRFPqdnddyw3IqjTOrsuBhI4LuXyNyT+a/ErCvijz6SbPN/H8ZDsmofPc3zN50qG+PPt/GnUvsUg0dTIJ3oEnmHyHyfUhFW7J9zV5rMm7m/y1Ce52/51k5ENnX7Hm4cp7EgSwsa365UkaNPNQ90Y8z9J89iGdCP3ctHSC+ojQ66DPEToD/kfN6Cq6jjNuwD+1stzVWz4Xt/CLTSiT356VsBFI6Y0mkP93meBinvNWbLFCj5MK8GKl/DOJukcsEsmrSZj83G7ytSZMhq5MPt8EtzurmTeY4MH4cBMmHG8xeakJqxw+4Mfk466lFVC+kyCwZb88SYNmHrpFnz23Nqo+CxAQoddBW9NhRuZlf+yjD1WEZFhZttzB7BN/igkuZr5/n8mxCR1ShTTXbHssMOcHV9dMHr7wgBNudyZEkPRrJ7Ajz3NNfsKEwEO8C/eYvMTESX5JXZTnvBBY0y/PqyX/39t27tsD54bdrusjQq+rd03nH5n3p6x6uI5ZwbPaJnhrjmSu7PfvNPlyE4jqz02+1OTYhE5Q3g8f6v2T9u/3Hr5v3ZnYt6f9YASZ4zr3lfrcs8HtFYe0HkzJiv7ZW1dY5R8NgTX98miVTD5oT21JNlnJMgiI0OsorekwI/NC6Hea/JDJZ5o8zoQV59SHZ7OKJz2r5JeZnILQ8SZgW1MBehnb7E2Dm5/AQSYz7JffNLlhkj3OQ/5I4kwOsvl9fz5uxXAs7m9MrmcaMndk8Mrysefvx+zY82e7oPTQUG/iAvxzv33JeBZ68i1tX9l02vShJu8XfmCb5RhHB9f0y5oKS0zQz9/O2BsTzEeFgvBgtWJiwOvjD3k+0P79YBMm6R9h4rE3tdiBSzpyN9M99FMvAiL0OmJrOv/IvOzzPsYkktTc8bW4GoaQ/JjWMVfokNRXm7DfH/f+4+DEYMagc91rsDPpY+xAnNj0PALMGGQZMKk/R96mBt3ySFxJpMQ/4F2hrLtNftmkJOMYY+GxF0wE0Pd7B/3RBmzh202Y4DHR87IgCiL0iVFgMsfEL3PE0duKLpjIUMd418GI9jn21AmbYLy516Q8TsnRQf5GHX7XMw3+d02/jFW5sv98pQmBpx5h7vrxmAwm3eURSPeYoT8wZ1vs5SZz9sUJjV89pCffI0x8Qu/xJmXswBbHPwerQsVthYAIvY7sms4/Ou9zDp2flebcUTBWDL9twqDiK1QPRDsmoZdeAgiNILW/NPn9w+DkxMNK/lsrg98Se4+xAz2r6/gsyJEV8Z8c6jQVr3B1GIxbR+IoG10wOWB19XUmsczSVoiZAKepLQpIFo9LDPrjGWXbW0ccPW7AJ4puN47FqPZR3+82YZyBrK9nFOsTwbdZGuIgWrEivTaypl/6s2JMxtRFTxAqpytebVIGVuI144MHDYzZ5vnEibayxfZ3IS3l8bcfazRce+q9lrGj9CL0ujLXdP7ReVnpMWAzgMwdX2OwgcyZwbt73ldCxyT0uNePx4ABemow9yA26peJgp/qeiVB3bSEmVXqkq4MQf+mybccdEIZ/K28ha50t2MXbJkw2PuntBVWbb7nH13iuHNxsfoHbwQfX61F70Rma2Yu/cj2lfWE4B9v4tsItKHcSiDPv5lAeiM/a/ol9XCijpOluGUS2+GBlUyU4nEy/s4FRtgOK/iaTcRneXAn/Yjy38vEt1OmjsaOPP45En+VdQQEbgVCb51NrcEcO0XvjHfNwFHLiwv2DhPOlc8dX4NI7zWB+J1UfeA8JqEz+WDVwYczsjy73CvODH495h/d/PF7TxnZtBAOEyXa5StQcAZ7n0C5u/2RB10wCPvZfD+BwPOiviFidMclN6xQmTT4rXbkwZvxApPrQ1m4bf3Uw5V9JyqfSUz01Ey1aW5FP6p97iVyUmIyiuA98XZRv7iVAIk7TlMr16k2tf6+pl/6JIfjj+BPWXhT/sDECZZ2gD9tiO2I+qaO5UkMyBrdeTm0/zUm/iwwY/8cb5DHaLSOxo44/tnCU7+fIQJ7J/TW2dQ5lXinODWh/5JVMl7SMnV8LRKpD/bx0ompdqwZ6Er8rg6Dk6+Owf+FJm81YbXiHwYk9k1xSbIy90H8c+379YJ+Er0TvfrqeVxJNgzGc/ugtJ80PqiXJxXKunpkfrwQx+vne+WObTxJQBqI0ld+cyci4h0Bpb5Gto8JyvubQG7U/Y6DLdRc6b6iZdXJpIg9/e836Xl/QUuPa+y83EZiy4OtsDLgknawheSu8ilvSfRCoIPoeo93R7j9lJObNW1p4aTfLxiBvRP6CNX0EsSazjaVNwa71Qbr6HKOA3amLpk0WRwZuFm5QNIE8LC6YJ+2dkc6qx7OyPv574yreKoeI9sw19bYPlbh7Iu3LvuJ2ySlLZX/n4uRoF7RDsq8ET8nULw65Sd6cqLrnXQj21d6H7hPYW5vvJx8j15lrrER92iAERPTOe+Bu9VvWLr/NKldw+wTJ+8b7npnZc5RS/5OGlbl6Ks8tbCmLXP2rd8uHIG9E3rp6u1Rl+9RnQOhxxVCjfgiacRBOtPxM2myuJWDMkFw1zOZ3f3IqpMBLLqRs88k3cg2zD23l3SYtDBAc21vbdsj1jtOyqbqMHdhT1xdkx+vTkk8JcbR9U6eke0rJxXucmey91smx34RzlIbubK6+nYGfe/zTKK3qaYrPDK/aEIE+9Q9DL4nH/fJCSCNrnbKrsUSLG1LT59S2gtEYO+EjuH7flOPeso9KvJm70pe09mm8jKo+IUxvjcZg77iyi5GeGfqkknTg11v2jjglW7kbFnR5Y7unmLiAWPZMtakQz9+Ztzf4oZbltez3mvCfrgHQUVbKlex7qKeqktLV3Orb8qMOM2t4svnL2lfLWYA2/04E8idrSPInZX4tcnoqPayDS3spjAvrzGeu/Y5luEehrlA1jKSHZvxmJN44+GotqyxceW9AARuBUKPA2hWJUs7P+VvlXcqkCkSPAOvryaydVlT3yyec+niFgLeBY/o7yn7mEFxXi9ffT/D/sBRM6L5cY3+uwkR7lwyUpLUnMs94wlq6SpejsN3jsnFF80wYYIwqGck/xrWI9o3FxOArUJg1PPrTZjYEWT2xyYxor/HDubStrCbypvRS/a5ZbrS9c7vHhR3w75PeTGWtmUUlirnTBEQodcVs6bDbJU3kl2c9UcXfHTN07JMXTJptjTfEc+Pkd0+SPqb3nrrDp7s995rwq1cZeCT40pQFDEABC1OrS6v7DduRuN3SHRrQqduU+fxI0atSHjqOaJ91MfPbnNtMfKGCbyYlIHVU03e04RXg9aw79Wnp19qZ+W2yG2dFWgdI/NJD/vmfOjb72Ey52Fa2pbOqiv5pSEgQq9rbE2H2SpvdJHG42vlue94KUmmLpk0W9p1nJzMuSdbdYjbDmvuj2cVC+kwqH6Rib/cxp8P4bPPGe+IvzqQEVeacnwJQiJY7jcOmXAtt/bQMyvBjK7iPnu8yCRO/OYCEEe2zzFjksVxvDtMuO0O/bAPPeVux9a5pa8VcNiyifh7BrtaeWW+JVt4cwF+2NvvmPiNcVOR7SPa0oOX0l4gAiL0utKWdn5K2ypvufL042seSMaz4/G2bF3W1LdErwxCzNwpHffNl+6hU48YDLg0Yr5cucZ4BJ7h7tBPs++sHj0qnGN5bzLhfDX3BrB37i73OXx7sc+kv7Jn+7ZL/A6J+nG4qWj60e2bGhI9+M6PL3JUjStOOb7lq/JWxH/vcJvBrlZmPH43+o4D6gQGTFzAHvu7NmEi9uiDvmp1WtqWXsyU/sIQEKHXFbamw2yZN15CwcqcG7VYSXI8qRbklKlLJk3WrBn8GIxYkRIc5nWbyx9Js4y6zj6XdGXEPJOb3nPt8Qxw7RKfiLGvpFrPiJOUY7jcwSLaCfjebcJ97wRSXpnEOIuI8cj29UzuqNPtJpw/f6bJ9cGOOB3QeoFJ1kaW2jl184DU7EmMTNsplwmM31GAneDZIebBj775mwPLNi5tSxYrpbtQBETodcWt6TBb5qVsbgfzt6/xwg9/gUgtoCxTl0yarHmXg1/t6FRJIO5ahUAZzH0vMfvMmI5BEUy4kITy7jFpEa7nL/cyY1mephcrr4Pv5x+L0GM0OxMs3rrnb+2Lnoy1RDHXPurAJMIndzyrdfKgF98eG1lTNhNNPwIIfnNX0/r5cX+pCrEItbsYmHTFOxjYxnEvj0e6k6Z25n1NW3owU9oLQ0CEXlfYmg6zZV4IM7pTcetyh/i1SRx0eghoTX1r6EVX6ZzrkLb8oIm/nKUVdZ3pWpTJqscHQQ/I4ka62tvOKBM3J1HW5PV98ZLca3j6ufGp962Da1xxUsaxCD2uJGlfaSfldaRbtK/cImrdqgf+3Lp3w4To7hiRn9F9K80aO4fE43W/3MfOpLr0HtBmbuv7+8PvtKnmDaEuxFrgWUM/N02YzLLdED1LUwFyZVt8kt/CQL/vHAERel3Bazr/1nmji5pBj/23qUtJMnUp0yy5+z7ulUOGuN6ffYAWon6iyb2HQZE/s7KDdBkoWU37ai6erV/a9RgEeYe0v9mMAfOGCcGC4OW3bvl967ymlFWkR6tf2ffoCo314Dd3v/J3vyyF6G2/n5y24T7m7DnPi5Ha8Uwz+TP6ic/vSR89NtgM2LbOno9uX9zCgOyYvFEPSMv1wI2C6As9sDWAPcTtk9j+Nd97sCuf46R746BP2vI9JkTlsxLnqCL2xBHGHzHxy2BqXp4y6K0MioueKne9+5W+Xq/oqfO6MbmgHnwysStrsFTeM0VAhF5XzJrOv3Xe6DJlcGA1EyObY4sydYlpypvCMmYbL+Hx9KzGuCXOB7Yr+85xHwZvPrychXo/YMJvEGjWNZ6pExjRlvi6UgZHvBl+MYgHr8WzvuS5aXLjUL/as8qVJuWSz1+EQ0RzPIPOb48ycaLyd8VTdkY/sQ496eM5dNdRxgsysn2+So+6hYDAw/Xg5/ZdD9gDK3VWrOWVpxndT6Xpwa5WBpNUbomLNkVdmbzxwaa5f8AncNhgGUPi7nj0QNsok2N6ZTR/nAj55MZvlONZZXAemHJhD/2r1h/X4Ka8F4SACL2urDWdf+u85SqPFsQI5tiiTF1KN3Cv+dbyM3Cxf31twvub+bf8kIb9c84bjyRzfw71Yv+S1TcEUauDp2WA/FQTXORTd8972iv7wgRkzo1PWspkEH66yc+asH/srnDvdxn9RNx600dvDoN++d7zilreOcEa0T7Kz+IFNngQiMRnRTryxSzUoxe7GjZuU9gshMyEtPy43ml3uR0TXeiOS237w3Xl/SIeP/TnebBjidPa/lxrt/52IQjsldDdbdy61GFKTXSKpWVsnddJwTsubWCA8cCrkgBa7Yj1XWK2cxh71PtbrGAP+OEZflTnufb9pRMD45K6lHmcJPyq0fstwZtN2A9lNcPd2Y814dgZpM/gWBuky3IZcFlV4T6O7nbSsTf66SbcHudl4mLGW8FqNL5JrNdWetPTbtoI+VAvnt8KTKMNo9rnuPm2B+f6wQJs3D3segBP7OGmSdymKLFf+v9e7KaeA2FzbLFsC/g+xsS3Dl5r36MtkY+LighOpO0Qud/3XnuWewSYhIERgY1PMImeDLZ/OL4a75bHvphAZq+qXoqn8p0hAnsk9NJtvOStTWvKOEZeVjJcYuIf3Me1FU2mLkvc7KUptzDmGZDrlFv6GF3DXb24e8HOXb2c479eWAHKZB/V20UxpeuVv12ZuGvW00CyGf3EqvWmp36fHAp4pX3vIcu17avBShvAzLdfalsfC9Uxm60Xu1Yd3J68LegdAp+6rrXss9hf60gepO44UZ9aPy9ti77IPQg9em61Vb9fCAJ7JPQLgV7VFAJCQAgIASEwDgER+jgsVZIQEAJCQAgIgZMhIEI/GfR6sBAQAkJACAiBcQiI0MdhqZKEgBAQAkJACJwMARH6yaDXg4WAEBACQkAIjENAhD4OS5UkBISAEBACQuBkCIjQTwa9HiwEhIAQEAJCYBwCIvRxWKokISAEhIAQEAInQ0CEfjLo9WAhIASEgBAQAuMQ+F9sgNYKIgd0wQAAAABJRU5ErkJggg==
Only by accepting this src, example /image.png and don't data:image
In debug...
I was reading a bit on this question but did not understand, and do not know if this is the problem Convert Data URI to File then append to FormData
any help is welcome...
I am sending a bufferedImage over a socket and I am using the example found in this post:
Sender
BufferedImage image = ....;
ImageIO.write(image, "PNG", socket.getOutputStream());
Receiver
BufferedImage image = ImageIO.read(socket.getInputStream());
It works - IF, and ONLY IF, I close the sender's outputStream after this line:
ImageIO.write(image, "PNG", socket.getOutputStream());
Is there anything I can do apart from closing the outputStream?
Also, is there anything else I can do to avoid using ImageIO altogether? It seems to take ages to do anything.
Also note that reading or writing to the hard disk in anyway should be avoided at all costs due to performance issues. I need to make this transfer as fast as possible, (I'm experimenting and trying to create a client similar to VNC and saving each screenshot to the hard disk would greatly slow down everything)..
#Jon Skeet
Edit 3:
Sender: (Note that I am sending a JPG image not a PNG).
int filesize;
OutputStream out = c.getClientSocket().getOutputStream();
ByteArrayOutputStream bScrn = new ByteArrayOutputStream();
ImageIO.write(screenshot, "JPG", bScrn);
byte[] imgByte = bScrn.toByteArray();
bScrn.flush();
bScrn.close();
filesize = bScrn.size();
out.write(new String("#FS " + filesize).getBytes()); //Send filesize
out.write(new String("#<IM> \n").getBytes()); //Notify start of image
out.write(imgByte); //Write file
System.out.println("Finished");
Reciever: (where input is the socket input stream)
Attempt #1:
String str = input.toString();
imageBytes = str.getBytes();
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
System.out.println("width=" + image.getWidth());
(failed: Nullpointer exception on getWidth() line)
I understand this error to mean "corrupt image" because it couldn't initialize it. correct?
Attempt #2:
byte[] imageBytes = new byte[filesize];
for (int j = 0; i < filesize; i++)
{
imageBytes[j] = (byte) input.read();
}
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
System.out.println("width=" + image.getWidth());
(failed: Nullpointer exception on getWidth() line)
Attempt #3:
if (filesize > 0)
{
int writtenBytes = 0;
int bufferSize = client.getReceiveBufferSize();
imageBytes = new byte[filesize]; //Create a byte array as large as the image
byte[] buffer = new byte[bufferSize];//Create buffer
do {
writtenBytes += input.read(buffer); //Fill up buffer
System.out.println(writtenBytes + "/" + filesize); //Show progress
//Copy buffer to the byte array which will contain the full image
System.arraycopy(buffer, 0, imageBytes, writtenBytes, client.getReceiveBufferSize());
writtenBytes+=bufferSize;
} while ((writtenBytes + bufferSize) < filesize);
// Read the remaining bytes
System.arraycopy(buffer, 0, imageBytes, writtenBytes-1, filesize-writtenBytes);
writtenBytes += filesize-writtenBytes;
System.out.println("Finished reading! Total read: " + writtenBytes + "/" + filesize);
}
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
(failed: Reciever gives: Null pointer exception)
Attempt 4:
int readBytes = 0;
imageBytes = new byte[filesize]; //Create a byte array as large as the image
while (readBytes < filesize)
{
readBytes += input.read(imageBytes);
}
InputStream in = new ByteArrayInputStream(imageBytes);
BufferedImage image = ImageIO.read(in);
in.close();
System.out.println("width=" + image.getWidth());
(failed: sender gives: java.net.SocketException: Connection reset by peer: socket write error)
Attempt #5:
Using Jon skeet's code snippet, the image arrives, but only partially. I saved it to a file (1.jpg) to see what was going on, and it actually sends 80% of the image, while the rest of the file is filled with blank spaces. This results in a partially corrupt image. Here is the code I tried: (note that captureImg() is not at fault, saving the file directly works)
Sender:
Socket s = new Socket("127.0.0.1", 1290);
OutputStream out = s.getOutputStream();
ByteArrayOutputStream bScrn = new ByteArrayOutputStream();
ImageIO.write(captureImg(), "JPG", bScrn);
byte imgBytes[] = bScrn.toByteArray();
bScrn.close();
out.write((Integer.toString(imgBytes.length)).getBytes());
out.write(imgBytes,0,imgBytes.length);
Reciever:
InputStream in = clientSocket.getInputStream();
long startTime = System.currentTimeMillis();
byte[] b = new byte[30];
int len = in.read(b);
int filesize = Integer.parseInt(new String(b).substring(0, len));
if (filesize > 0)
{
byte[] imgBytes = readExactly(in, filesize);
FileOutputStream f = new FileOutputStream("C:\\Users\\Dan\\Desktop\\Pic\\1.jpg");
f.write(imgBytes);
f.close();
System.out.println("done");
The sender still gives a Connection reset by peer: socket write error.
Click here for full sized image
One option would be to write the image to a ByteArrayOutputStream so you can determine the length, then write that length to the output stream first.
Then on the receiving end, you can read the length, then read that many bytes into a byte array, then create a ByteArrayInputStream to wrap the array and pass that to ImageIO.read().
I'm not entirely surprised that it doesn't work until the output socket is closed normally - after all, a file which contains a valid PNG file and then something else isn't actually a valid PNG file in itself, is it? So the reader needs to read to the end of the stream before it can complete - and the "end" of a network stream only comes when the connection is closed.
EDIT: Here's a method to read the given number of bytes into a new byte array. It's handy to have as a separate "utility" method.
public static byte[] readExactly(InputStream input, int size) throws IOException
{
byte[] data = new byte[size];
int index = 0;
while (index < size)
{
int bytesRead = input.read(data, index, size - index);
if (bytesRead < 0)
{
throw new IOException("Insufficient data in stream");
}
index += bytesRead;
}
return data;
}
for other StackOverflow users like me.
In "Jon Skeet's" answer. Modify the following line of readExactly method.
<<original Line>>
index += size;
<<modified Line>>
index += bytesRead;
To get the full image data.
public static void main(String[] args) {
Socket socket = null;
try {
DataInputStream dis;
socket = new Socket("192.168.1.48",8000);
while (true) {
dis = new DataInputStream(socket.getInputStream());
int len = dis.readInt();
byte[] buffer = new byte[len];
dis.readFully(buffer, 0, len);
BufferedImage im = ImageIO.read(new ByteArrayInputStream(buffer));
jlb.setIcon(new ImageIcon(im));
jfr.add(jlb);
jfr.pack();
jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfr.setVisible(true);
System.gc();
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
In 192.168.1.48:8000 machine python server running and i got stream in java code
I have the following code to read blob data & display the result as an image. But I'm getting the error java.lang.IllegalStateException: getWriter() has already been called for this response.
while (rs2.next()) {
Blob image = null;
byte[] imgData = null;
j++;
qPaperOptions = rs2.getString(1);
int qDetailId = rs2.getInt(2);
image = rs2.getBlob(5);
ServletOutputStream sout = response.getOutputStream();
// o.close();
// imgData = image.getBytes(1,(int)image.length());
// Blob cnt_data=rs2.getBlob("cimg.ctn_data");
if (image != null) {
// imgData = image.getBytes(1,(int)image.length());
response.setContentType("image/gif");
InputStream in = image.getBinaryStream();
int length = (int) image.length();
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
while ((length = in.read(buffer)) != -1) {
sout.write(buffer, 0, length);
}
}
}
What can I do to resolve that error?
Which line is throwing the exception? In general the code looks correct. Just a couple of ideas:
Could it be that you're iterating over this code twice (two results or more in the resultset)? Also, try setting the contentType before getting the output stream.
I'm trying to develop an application in Android and I'm having a problem I can't figure out how to solve.
Description:
The application consists of image processing and one of the routines is as follows. An image file (PNG) is converted into a array of bytes databyteimage[] with n elements, a part of this array ex: from databyteimage[i] to databyteimage[i+k] consecutive with k elements and " i " is offset databyteimage[], the LSB (Least Significant Bit) is replaced, the value what is replaced coms from other array of bytes ex:datareplace[] with m elements the value of k is m*8. This operation is done using operations on bits . After this process, a new string databyteimage[] is created.
The problem:
When trying to create the BITMAP object from the new array databyteimage[] returns NULL to displaty or show the new image.
I would appreciate if you could help me find a solution to this problem, since until now no one could help me.
***// GetByte method from Image***
private byte[] getByteImageData(String filePath) {
/*
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
Bitmap mutable = bitmap.copy(Bitmap.Config.RGB_565, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
mutable.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
*/
byte[] _imagebytedata = new byte[1024];
InputStream _input = null;
try {
if (filePath != null && (filePath.length() > 0)) {
// Create a file for image
File _fileimage = new File(filePath);
if (_fileimage.exists()) {
// Get the byte from file image
_input = new BufferedInputStream(new FileInputStream(
_fileimage));
_imagebytedata = new byte[(int) _fileimage.length()];
_input.read(_imagebytedata, 0, (int) _fileimage.length());
_input.close();
}
}
} catch (Exception e) {
}
**// Bitwise operations to change LSB of byte array image**
private byte[] Text(byte[] imagedata, byte[] textmess, int offset) {
for (int i = 0; i < textmess.length; ++i) {
int add = textmess[i];
for (int bit = 7; bit >= 0; --bit, ++offset) {
int b = (add >>> bit) & 1;
imagedata[offset] = (byte) ((imagedata[offset] & 0xFE) |b);
}
}
return imagedata;
}
***//Save image from new byte array***
private boolean saveImage(String pathFile,byte[] encodedimage) {
OutputStream _output = null;
File _newFileImage = new File(pathFile);
byte[] _encodedimage = encodedimage;
//Bitmap _imagebitmap = BitmapFactory.decodeByteArray(encodedimage, 0, encodedimage.length);
if (_newFileImage.exists()) {
try {
_output = new BufferedOutputStream(new FileOutputStream(
_newFileImage));
_output.write(_encodedimage, 0, _encodedimage.length);
_output.flush();
_output.close();
return true;
} catch (Exception e) {
}
;
}// _newFileImage.exists()
return false;
}
public boolean encodeTextInFile(String filepath, String text) {
byte[] _newimagebytedata;
byte[] _imagebytedata = getByteImageData(filepath);
byte[] _textbytedata = text.getBytes();
byte[] _lengthbytedata = byteConversion(text.length());
_newimagebytedata = Text(_imagebytedata, _lengthbytedata, 33);
_newimagebytedata = Text(_imagebytedata, _textbytedata, 65);
**// The value of variable _bitmapdoi is null here is the problem**
Bitmap _bitmapdoi = BitmapFactory.decodeByteArray(_newimagebytedata, 0,_newimagebytedata.length);
return saveImage(filepath, _newimagebytedata);
}
What you are reading in getByteImageData is not a bitmap. It is a file, most likely a compressed image. Working on the bytes from this file is very different from working on the image pixels. I suggest you work on the actual Bitmap object:
Load the bitmap:
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
// Not quite sure if the returned bitmap is mutable, so
Bitmap mutable = bitmap.copy(Bitmap.Config.RGB_565, true);
Modify a pixel:
int pixelRGB = mutable.getPixel(x, y);
// Do whatever you have to do
mutable.setPixel(x, y, pixelRGB);
Write it back:
mutable.compress(Bitmap.CompressFormat.PNG, 100, new ByteArrayOutputStream(new FileOutputStream(_newFileImage)));
I have a problem and can not solve in my application. The application performs operations on images like PNG, the image is convert in a byte array, then a piece from this array of bytes is performed on bitwise operations, the problem is the new series of new bitmap format byte is always null. I just do not understand why the new bitmap, from new array byte, is always null and not know how to fix it this bug.
// GetByte method from Image
private byte[] getByteImageData(String filePath) {
/*
Bitmap bitmap = BitmapFactory.decodeFile(filePath);
Bitmap mutable = bitmap.copy(Bitmap.Config.RGB_565, true);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
mutable.compress(Bitmap.CompressFormat.PNG, 100, baos);
return baos.toByteArray();
*/
byte[] _imagebytedata = new byte[1024];
InputStream _input = null;
try {
if (filePath != null && (filePath.length() > 0)) {
// Create a file for image
File _fileimage = new File(filePath);
if (_fileimage.exists()) {
// Get the byte from file image
_input = new BufferedInputStream(new FileInputStream(
_fileimage));
_imagebytedata = new byte[(int) _fileimage.length()];
_input.read(_imagebytedata, 0, (int) _fileimage.length());
_input.close();
}
}
} catch (Exception e) {
}
// Bitwise operations
private byte[] Text(byte[] imagedata, byte[] textmess, int offset) {
for (int i = 0; i < textmess.length; ++i) {
int add = textmess[i];
for (int bit = 7; bit >= 0; --bit, ++offset) {
int b = (add >>> bit) & 1;
imagedata[offset] = (byte) ((imagedata[offset] & 0xFE) |b);
}
}
return imagedata;
}
//Save image from new byte array
private boolean saveImage(String pathFile,byte[] encodedimage) {
OutputStream _output = null;
File _newFileImage = new File(pathFile);
byte[] _encodedimage = encodedimage;
//Bitmap _imagebitmap = BitmapFactory.decodeByteArray(encodedimage, 0, encodedimage.length);
if (_newFileImage.exists()) {
try {
_output = new BufferedOutputStream(new FileOutputStream(
_newFileImage));
_output.write(_encodedimage, 0, _encodedimage.length);
_output.flush();
_output.close();
return true;
} catch (Exception e) {
}
;
}// _newFileImage.exists()
return false;
}
public boolean encodeTextInFile(String filepath, String text) {
byte[] _newimagebytedata;
byte[] _imagebytedata = getByteImageData(filepath);
byte[] _textbytedata = text.getBytes();
byte[] _lengthbytedata = byteConversion(text.length());
Bitmap _bitmapunu = BitmapFactory.decodeByteArray(_imagebytedata, 0, _imagebytedata.length);
_newimagebytedata = Text(_imagebytedata, _lengthbytedata, 33);
Bitmap _bitmapdoi = BitmapFactory.decodeByteArray(_newimagebytedata, 0, _newimagebytedata.length);
// The value of variable _bitmapdoi is null
_newimagebytedata = Text(_imagebytedata, _textbytedata, 65);
return saveImage(filepath, _newimagebytedata);
}
It looks as if you are trying to encode a text message in the lower bits of the image (if I understand your code correctly). I actually used this as a christmas card for fellow geeks this year.
However, when you create Text you encode the text into the byte[] of the image file thus probably destroying the image (unless you are very lucky). You probably want your addition of the text bytes to be on the decoded image (Bitmap _bitmapunu).
The javadoc for Bitmap.decodeByteArray says that it will return null if the image can not be decoded.
This is what you need to do:
Read the image bytes from the file, say fileArray.
Decode the fileArray into actual pixels, imageArray
Manipulate the pixels in imageArray
Encode the pixels into a image format again (such as png), say newFileArray.
Store the newFileArray to a file.
What you seem to be doing is trying to manipulate the bytes in fileArray directly, thus breaking the file format and making it impossible to decode the bytes into pixels.