i have a requirement, i want to take URL of image from user and then convert it to bytes format, and send it my server, i am using tomcat as web-app server and hibernate as ORM tool, i am already written the server side code for saving the incoming bytes into a table using BLOB, but my problem is that how can i convert the image into array of bytes, so that i can send the array to server to process further.
And adding to above, i can load the data, from table, and then can send the bytes back to client, but how to convert the bytes back to image.
Currently, i am using HTML at client side for web pages and Servlets for request and response.
Please help me.
If it's an image URL, then just read the URL straight into a byte array, like this:
public static byte[] getBytesFromURL(URL url) throws IOException {
InputStream in = null;
ByteArrayOutputStream out = null;
try {
in = url.openStream();
out = new ByteArrayOutputStream();
int len;
byte[] buf = new byte[1024 * 4];
while ((len = in.read(buf)) >= 0) {
out.write(buf, 0, len);
}
byte[] bytes = out.toByteArray();
return bytes;
} catch (IOException e) {
throw e;
} finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
}
}
}
}
Check the ImageIO class in java. It has methods for both reading and writing images. For more information check here.
It seems that you dont need to do any special computation on your images. Just store them and send them back to a browser. If this is the case, you dont actually need to treat them as images, you can just handle them as java.io.File. Then you can store them as BLOB in your database.
To help you manage the upload you can use commons-fileupload. Or if you are using SpringMVC, have a look at the Multipart Resolver.
Related
First, I get the Uri of the file I want to send. I know the Uri is correct because I was successful in converting the Uri to Bitmap and display it.
Next, I convert the Uri to an inputStream using the code:-
public InputStream uriToStream(Uri uri) throws FileNotFoundException {
InputStream is = getContentResolver().openInputStream(uri);
return is;
}
Next, I convert the inputStream to byte array(byte[]) using the code:-
public byte[] streamToByteArray(InputStream is) throws IOException {
int nRead;
byte[] by = new byte[16384];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((nRead = is.read(by, 0, by.length)) != -1) {
buffer.write(by, 0, nRead);
}
return buffer.toByteArray();
}
Next, I used this code to establish a connection with the server and send data
public class threadClient extends Thread {
byte[] ByteFile;
threadClient(byte[] byteFile) {
ByteFile = byteFile;
}
public void run() {
try {
Log.i("network","connecting....");
Socket client = new Socket("192.168.0.120",6666);
Log.i("network","connected");
Log.i("network","sending data");
DataOutputStream stream = new DataOutputStream(client.getOutputStream());
stream.writeInt(ByteFile.length);
stream.flush();
stream.close();
stream.write(ByteFile);
stream.flush();
stream.close();
Log.i("network","data sent");
} catch (Exception e) {
Log.i("network",e.toString());
}
}
}
The server is running python. After the server accepts the connection from the client the server uses the following code to handle the client
def client_handler(client,address):
print(f"Accepted connection")
size = int(jpysocket.jpydecode(client.recv(1024)))
print(f"file size = {str(size)}")
with open("test.pdf","wb") as file:
file.write(client.recv(size))
print("file saved")
first, the server receives the size of the file, and then it receives the byte array and writes the file.
But surprise the file is corrupt......
PLEASE CAN SOMEONE HELP......
THANKYOU
Cause you are filing byte array more than image's bytes.
for example if the image's byte's lengths is 1024, you are initializing byteArray with 16384 size, the byte become [1,2,3,4, 0, 0, 0, 0, //more zero till the end of byte array's size]
// 1,2,3,4 is your bytes and 0 are unused bytes
try to initialize byteArray with size of image's byte's lengths to get the correct result.
I'm able to successfully send, the encoded video byte[](in string) of any size, response from server, but while downloading in mobile i always encounter MemoryOutOfBoundException when the video requested exceeds 3.5mb(approx), otherwise works fine.
The code below is the one I'm currently using.
String image = (encoded byte[] in form of string from server);
byte[] byteImageData = new byte[image.length()];
byteImageData = Base64.decode(image, Base64.DEFAULT);
System.gc();
BufferedOutputStream out = null;
try {
out = new BufferedOutputStream(new FileOutputStream(file));
out.write(byteImageData);
out.flush();
} catch (IOException e) {
e.getMessage();
}
finally {
if (out != null) {
out.close();
}
System.gc();
All I need is that the mobile should be capable enough to download atleast 20mb.
Can anyone please help me out to overcome this problem?
I would suggest to use Android's Download Manager https://developer.android.com/reference/android/app/DownloadManager.html
Then Check register for broadcast receiver to listein for file download.
Please check this example: http://blog.vogella.com/2011/06/14/android-downloadmanager-example/
I need to upload image (jpeg, png, gif) and audio (mp3, wav, aa3) to web server. So I need to convert image into byte array. How do I do that?
Now I am try following format. But it increases the size. How do other applications do this without increasing size quality? They upload the original size and image quality.
Bitmap uploadedImage = ((BitmapDrawable) temp.getDrawable()).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
uploadedImage.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bytes = stream.toByteArray();
Original images increase in size when converted to a bitmap because all the image formats you mentioned use some form of compression (some lossless, some not). When you use a bitmap, there's no compression used.
You could read the raw data of the drawable into a byte array and send that to the server. You can check that answer Reading a resource sound file into a Byte array to see an example of how this could be done.
Presumably you have the Image in some sort of form already? Don't try to decompress or process it, just send it to the server as a stream of bytes. For example if it is already a file on your computer:
public String postFile(URL url, InputStream in) throws IOException {
try {
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
connection.setRequestMethod("POST");
connection.setChunkedStreamingMode(CHUNK_SIZE);
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type","application/octet-stream");
try (OutputStream out = connection.getOutputStream()) {
byte[] buffer = new byte[CHUNK_SIZE];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
if (connection.getResponseCode() != 201) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getErrorStream()))) {
// TODO: Handle error
}
} else {
try (BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()))) {
// TODO: Handle success
}
}
} finally {
connection.disconnect();
}
}
To send a file just pass in the FileInputStream, to send bytes you can simplify the function above so it doesn't need to read from the stream and can just send the byte buffer on the output stream.
To get an InputStream for a local file you just need:
File file = ....
try (InputStream is = new FileInputStream(file)) {
postFile(url, is);
} catch (FileNotFoundException ex) {
// TODO: Handle error
}
No need to compress. Just send as stream. once got the image uri do the following..
InputStream iStream = context.getContentResolver().openInputStream(uri);
and use the iStream into write the httpsurlconnection.
I have a web service, which gives me a json having a node named as 'imagedata'. It contains a huge data as a string. When I print this in browser it gives me valid input. Base64 encoded strings ends on '=' character.
I have also tested it using this tag in a html page, and it works perfectly fine.
<img src="data:image/png;base64,MY_BASE64_ENCODED_STRING"/>
Here is my code;
StringBuilder b64 = new StringBuilder(dataObj.getString("imagedata"));
byte[] decodedByte = Base64.decode(b64.toString(), 0);
bitmap = BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
Kindly note that, This code works on smaller image-data but gives bad-base64 exception on larger image-data
Kindly help me out,
Thanks
Why your server give you the base64 encoding?. Base64 it is just communication not to encoding image. If it use for encoding it will make your image file size bigger.IllegalArgumentException mean your image encoding incorrectly formatted or otherwise cannot be decoded.
In my project i just, for now, i use the Base64 for sending image. But it will be change by multipart. But when server forward to the recipient. It just forward the url of image. So i can do simple process the url to Image with this:
public static Image loadImage(String url)
{
HttpConnection connection = null;
DataInputStream dis = null;
byte[] data = null;
try
{
connection = (HttpConnection) Connector.open(url);
int length = (int) connection.getLength();
data = new byte[length];
dis = new DataInputStream(connection.openInputStream());
dis.readFully(data);
}
catch (Exception e)
{
System.out.println("Error LoadImage: " + e.getMessage());
e.printStackTrace();
}
finally
{
if (connection != null)
try
{
connection.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
if (dis != null)
try
{
dis.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return Image.createImage(data, 0, data.length);
}
Note this code for J2ME.
I have an Android application where I'm trying to send a picture to a server. I did this using Base64 encoding and it worked quite well, but it took too much memory (and time) to encode the picture before sending it.
I'm trying to strip the Android application down to where it just simply sends the byte array and doesn't fiddle around with any kind of encoding scheme so it'll save as much memory and CPU cycles as possible.
This is what I would like the Android code to look like:
public String sendPicture(byte[] picture, String address) {
try {
Socket clientSocket = new Socket(address, 8000);
OutputStream out = clientSocket.getOutputStream();
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
out.write(picture);
return in.readLine();
}
catch(IOException ioe) {
Log.v("test", ioe.getMessage());
}
return " ";
}
The server is written in Java. How do I write the server code so I can properly retrieve the exact same byte array? My goal is to save as many CPU cycles on the Android as possible.
So far, all the methods I've tried resulted in corrupt data or a thrown exception.
Any help will be appreciated.
Try something like this:
public byte[] getPicture(InputStream in) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int data;
while ((data = in.read())>=0) {
out.write(data);
}
return out.toByteArray();
} catch(IOException ioe) {
//handle it
}
return new byte[]{};
}
Based on Robert's and Zaki's comment, here is the modified code that should perform better.
public byte[] getPicture(InputStream in) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int length = 0;
while ((length = in.read(data))!=-1) {
out.write(data,0,length);
}
return out.toByteArray();
} catch(IOException ioe) {
//handle it
}
return null;
}
If you want bi-directional communication, the server must know when you're ready - you should prepend a 4 byte length field to your sender side indicating the number of bytes to come.
On the server side you read the length and then stay listening until everything has arrived. Then you can reply your acknowledge string.
If it is enough to send only the picture, you can simply send the data and then close the connection. The server side is implemented as shown by #thejh.