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.
Related
I have been searching the web for this particular problem. Maybe i'm doing something wrong or i'm missing something here...
So i'm trying to convert a File Stream ( an Excel file ) -> mimetype ( application/octet-stream or application/vnd.ms-excel ) doesn´t matter...to a Base64 encoded string.
The reason i'm doing this is because i want to provide the File in a REST API inside a JSON object for later decoding in the browser the base64 string and download the file.
When I receivethe InputStream and save to the disk everything works fine...
Even when i use POSTMAN to get the FILE if I save the file it opens in Excel with all the right data.
THE CODE -> Used this simple example to download a file from a URL
URL url = new URL(fileURL);
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();
//etc...i get response code OK(200) get file name etc
// opens input stream from the HTTP connection
InputStream inputStream = httpConn.getInputStream();
String saveFilePath1 = "C:\\test1.xlsx";
String saveFilePath2 = "C:\\test2.xlsx";
FileOutputStream outputStream = new FileOutputStream(saveFilePath1);
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
//FOR TESTING PURPOSES AT THIS POINT I HAVE SAVED THE STREAM INTO
//**test1.xlsx** SUCCESSFULLY and opens into excel and everything
//is fine.
//THE PROBLEM RESIDES HERE IN THIS NEXT PIECE OF CODE
//import org.apache.commons.codec.binary.Base64;
//I try to encode the string to Base64
String encodedBytesBase64 = Base64.encodeBase64String(buffer);
//WHEN I DO THE DECODE AND WRITE THE BYTES into test2.xlsx this file doesn´t work...
FileOutputStream fos = new FileOutputStream(saveFilePath2);
byte[] bytes = Base64.decodeBase64(encodedBytesBase64);
fos.write(bytes);
//Close streams from saved file test2
fos.close();
//Close streams from saved file test1
outputStream.close();
inputStream.close();
I even took the string to check if it is a valid Base64 String, which it is accordind to this site -> Base64 Validator
But when i try to decode the string in the same website it tells me there's a different encoding:
Is it possible this is the problem ?
I think you can ignore those warnings. Rather, the issue is here:
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
:
String encodedBytesBase64 = Base64.encodeBase64String(buffer);
As you can see in the first part, you are reusing buffer to read the input stream and write to the output stream. If this loops around more than once, buffer will be overwritten with the next chunk of data from the input stream. So, when you are encoding buffer, you are only using the last chunk of the file.
The next problem is that when you are encoding, you are encoding the full buffer array, ignoring the bytesRead.
One option might be to read the inputStream and write it to a ByteArrayOutputStream, and then encode that.
int bytesRead = -1;
byte[] buffer = new byte[BUFFER_SIZE];
ByteArrayOutputStream array = new ByteArrayOutputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
array.write(buffer, 0, bytesRead);
}
String encoded = Base64.encodeBase64String(array.toByteArray());
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 trying load an image in a string and after do something with this String, save the image.
The problem appear when i try to asignate the value of the FileInputStream to the String targetFileStr. If i don't to this, and I save the image, everything it's ok, but when i save it on the String, the image change, no matter if I try save the image from the String or from the FileInputStream.
FileInputStream fis = null;
File file = new File("image.png");
fis = new FileInputStream(file);
String targetFileStr = IOUtils.toString(fis, "UTF-8");
*InputStream inputStream = IOUtils.toInputStream(targetFileStr, "UTF-8");
*InputStream inputStream = fis;
// no matter which one i use, both ways fail
OutputStream outputStream = null;
try {
outputStream = new FileOutputStream(new File("image2.png"));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, read);
}
} catch (Exception e) {
e.printStackTrace();
}
You may want to consider converting the image into a String via Base64 encoding/decoding. This is an example of encoding.
After encoding, you can modify the String (actually you create new strings, you cannot modify the existing one), but be sure to produce valide base64-encoded outputs, otherwise you won't be able to decode.
I have the following problem: I have an HttpServlet that create a file and return it to the user that have to receive it as a download
byte[] byteArray = allegato.getFile();
InputStream is = new ByteArrayInputStream(byteArray);
Base64InputStream base64InputStream = new Base64InputStream(is);
int chunk = 1024;
byte[] buffer = new byte[chunk];
int bytesRead = -1;
OutputStream out = new ByteArrayOutputStream();
while ((bytesRead = base64InputStream.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
As you can see I have a byteArray object that is an array of bytes (byte[] byteArray) and I convert it into a file in this way:
First I convert it into an InputStream object.
Then I convert the InputStream object into a Base64InputStream.
Finally I write this Base64InputStream on a ByteArrayOutputStream object (the OutputStream out object).
I think that up to here it should be ok (is it ok or am I missing something in the file creation?)
Now my servlet have to return this file as a dowload (so the user have to receive the download into the browser).
So what have I to do to obtain this behavior? I think that I have to put this OutputStream object into the Servlet response, something like:
ServletOutputStream stream = res.getOutputStream();
But I have no idea about how exactly do it? Have I also to set a specific MIME type for the file?
It's pretty easy to do.
byte[] byteArray = //your byte array
response.setContentType("YOUR CONTENT TYPE HERE");
response.setHeader("Content-Disposition", "filename=\"THE FILE NAME\"");
response.setContentLength(byteArray.length);
OutputStream os = response.getOutputStream();
try {
os.write(byteArray , 0, byteArray.length);
} catch (Exception excp) {
//handle error
} finally {
os.close();
}
EDIT:
I've noticed that you are first decoding your data from base64, the you should do the following:
OutputStream os = response.getOutputStream();
byte[] buffer = new byte[chunk];
int bytesRead = -1;
while ((bytesRead = base64InputStream.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
You do not need the intermediate ByteArrayOutputStream
With org.apache.commons.compress.utils.IOUtils you can just "copy" from one file or stream (e.g. your base64InputStream) to the output stream:
response.setContentType([your file mime type]);
IOUtils.copy(base64InputStream, response.getOutputStream());
response.setStatus(HttpServletResponse.SC_OK);
You'll find that class here https://mvnrepository.com/artifact/org.apache.commons/commons-compress
A similar class (also named IOUtils) is also in Apache Commons IO (https://mvnrepository.com/artifact/commons-io/commons-io).
I am able to send strings from my Android mobile phone to my computer, and vice versa. However, I want to send an image from my computer and display it to the mobile phone. In my case, the computer is the server and the mobile phone is the client.
This is part of my code on the server side:
socket = serverSocket.accept();
dataOutputStream = new DataOutputStream(socket.getOutputStream());
captureScreen("C:\\Users\\HP\\Desktop\\capture.png");
File f = new File("C:\\Users\\HP\\Desktop\\capture.png");
byte [] buffer = new byte[(int)f.length()];
dataOutputStream.write(buffer,0,buffer.length);
dataOutputStream.flush();
Note that captureScreen() is a method that successfully takes a screenshot of the server and save it as a .PNG image in the above path.
Now, on the client side which is the Android mobile phone, if I have an ImageView control, how to read the image sent from the computer as an InputStream and display it on the ImageView?
Furthermore, did I write successfully the image to the dataOutputStream? I would be glad if any one helps me !
You can call the setImageBitmap(Bitmap bm) of your ImageView.
http://developer.android.com/reference/android/widget/ImageView.html
How you get the image data to your client: it depends on the solution you have chosen, but technically you can use the same libraries that you would use for pure Java.
You can use android.graphics.BitmapFactory to create the Bitmap from your stream.
http://developer.android.com/reference/android/graphics/BitmapFactory.html
Bitmap bitmap1 = BitmapFactory.decodeStream(inputStream);
Bitmap bitmap2 = BitmapFactory.decodeFile(filename);
what is this ?
byte [] buffer = new byte[(int)f.length()];
dataOutputStream.write(buffer,0,buffer.length);
You just declared size of a buffer byte array , but it`s empty!
You should to convert your file to byte and than transfer it to OutputStream , smth like this:
byte[] buffer = System.IO.File.ReadAllBytes("C:\\Users\\HP\\Desktop\\capture.png");
(code for c#)
And than you will send it like you did:
dataOutputStream.write(buffer,0,buffer.length);
dataOutputStream.flush();
try this for file receiving :
public void fileReceived(InputStream is)
throws FileNotFoundException, IOException {
Log.i("IMSERVICE", "FILERECCC-1");
if (is!= null) {
FileOutputStream fos = null;
BufferedOutputStream bos = null;
try {
fos = new FileOutputStream("/sdcard/chats/gas1.jpg/");
bos = new BufferedOutputStream(fos);
byte[] aByte = new byte[1024];
int bytesRead;
while ((bytesRead = is.read(aByte)) != -1) {
bos.write(aByte, 0, bytesRead);
}
bos.flush();
bos.close();
Log.i("IMSERVICE", "FILERECCC-2");
} catch (IOException ex) {
// Do exception handling
}
}
}
}
So you`ll got new file in your sd-card on Android.