Speed up image download time - java

in my app I'm downloading images I get from an URL. The problem here is that it takes wayy too long. The images are compressed and only 9km big. I'm downloading 50 of them, so let's say 500kByte of images are being downloaded by the app. This should be pretty fast, right? Well, it isn't. I'm sometimes wating for 20 seconds until it's loaded. What is taking so long there? I have a pretty easy way to download the images. Here it is
int downloadingImages = getDownloadImageCount();
System.out.println(downloadingImages);
if(downloadingImages == 0){
for(int c = downloadingImages; c < 50; c++){
try{
bitmapArr[c] = getBitmapFromURL(imageURLArr[c]);
setDownloadImageCount(50);
publishProgress(c);
} catch (FileNotFoundException f1){
Log.v("FileNotFoundException", "Bitmap konnte nicht geladen werden");
} catch(NullPointerException e){
} catch (IllegalStateException ie){
}
setDownloadImageCount(50);
}
}
This is the getBitmapFromUrl function
public static Bitmap getBitmapFromURL(String src) throws FileNotFoundException {
try {
//Downloading the image
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
try{
//Saving the image to a bitmap and return it
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
//Catch Exception if file not found
} catch(FileNotFoundException ffe){
Log.v("FileNotFoundException", "getBitmapFromURLMethod");
return null;
}
//Catch Exception if error at input and output
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
I mean, what is taking so long there? How can I increase the speed. I will use cahing for images later, but still... I mean it's 500kbs and takes so long. Why is that?

Its completely natural that it takes a while. For each image you load from a URL a new HTTP-request is made (that is a request is sent to the server and it responds).
Thats 50 times the round-trip time over the network (not even including the time it may take the server to respond). You should cache the images locally once you have them retrieved.

The longest step in the process is probably sending a request to the server and waiting for it to respond, and you're repeating this step 50 times. Do you have the ability to modify the server? If so, consider adding an action that lets you download all 50 images at once (perhaps by putting them into a zip file, then unpacking them client-side).

Try to wrap your InputStream to BufferedInputStream
BufferedInputStream bs = new BufferedInputStream(input);
Bitmap myBitmap = BitmapFactory.decodeStream(input);

Related

Trouble downloading video file greater than 3.5mb

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/

Response fails to return image when outputBuffer bytesWritten < 8kb

Within a SpringBoot app, I am attempting to return images via a Response object's outputBuffer, via:
try {
response.setContentType("image/png");
InputStream in = new FileInputStream(pathToFile);
IOUtils.copy(in, response.getOutputStream());
}
catch (Exception e){
...
}
This works fine, unless the image is less than 8kb, in which case it just returns nothing.
Can anyone tell me why being less than 8kb would cause the Response to actually return zero data (and - crucially - how to remedy this)?
I've solved it by setting the content length explicitly in the header:
File actualFile = new File(pathToFile);
if (actualFile.exists()){
try {
response.setContentType("image/png");
response.setHeader("Content-Length", String.valueOf(actualFile.length()));
InputStream in = new FileInputStream(pathToFile);
IOUtils.copy(in, response.getOutputStream());
}
catch (Exception e){
...
}
}
I guess it didn't like not knowing the size of the content if it was below 8kb.

Java Applet hangs in IE when getting HttpUrlConnection outputstream

I have a signed file uploader applet that works in Chrome but seems to hang when run in IE. In IE, I can successfully upload a file (or set of files) one time but the next time I try to upload another file, the browser freezes and I have to close the browser. It seems to be happening when I attempt to retrieve the outputstream of the HttpUrlConnection object. Here is my code:
public void upload(URL url, URL returnUrl, List<FileIconPanel> files) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setDoInput(true);
conn.setUseCaches(false);
conn.setChunkedStreamingMode(1024);
HttpURLConnection.setFollowRedirects(false);
conn.setRequestProperty("content-type", "application/zip");
conn.setRequestMethod("POST");
//This zip output stream will server as our stream to the server and will zip each file while
// it sends it to the server.
ZipOutputStream out = new ZipOutputStream(conn.getOutputStream());
for (int i = 0; i < files.size(); i++) {
//For each file we will create a new entry in the ZIP archive and stream the file into that entry.
File f = (File) files.get(i).getFile();
ZipEntry entry = new ZipEntry(f.getName());
out.putNextEntry(entry);
InputStream in = new FileInputStream(f);
int read;
byte[] buf = new byte[1024];
while ((read = in.read(buf)) > 0) {
out.write(buf, 0, read);
}
out.closeEntry();
}
//Once we are done writing out our stream we will finish building the archive and close the stream.
out.finish();
out.close();
// Now that we have set all the connection parameters and prepared all
// the data we are ready to connect to the server.
conn.connect();
// read & parse the response
InputStream is = conn.getInputStream();
StringBuilder response = new StringBuilder();
byte[] respBuffer = new byte[4096];
while (is.read(respBuffer) >= 0) {
response.append(new String(respBuffer).trim());
}
is.close();
} catch (IOException ioE) {
ioE.printStackTrace();
logger.info("An unexpected exception has occurred. Contact your system administrator");
} catch (Exception e) {
e.printStackTrace();
logger.info("An unexpected exception has occurred. Contact your system administrator");
} finally {
//Once we are done we want to make sure to disconnect from the server.
if (conn != null) conn.disconnect();
}
}
I can see in the log files that it is freezing a this line:
ZipOutputStream out = new ZipOutputStream(conn.getOutputStream());
the second time I try to upload a file. This code also does work in IE under java 6. It has had this problem since I updated to the latest.
Is there something I'm leaving open that I need to make sure to close out before using the applet again? Been beating my head against this for the last two days. Sure hope someone can help...
I have an idea of what's going on but I don't know exactly the details of the what's causing the problem. I at least figured it out a workaround...I was using a jquery dialog box to display the applet. I was doing this on the fly so every time I open the dialog box, it was building the applet again. It's strange because I was in fact removing the div element that contained the applet every time the dialog box was closed so I would have thought that would ensure the old applet instance was destroyed as well. Chrome seems to be smart enough to destroy it and create a new one (or something to that effect) but IE has problems.

How to have ASP.Net Webpage read bytes from Java Android client?

I'm trying to upload images to External MS SQL database using android phone. I'm using Java HttpClient to send array of bytes to web server or web page. I don't know how I should approach this. The web page should be in ASP.net. I'm fairly new to ASP.Net. I did intensive research on how to read in a byte array using ASP.Net and still don't have an answer. I want my webpage or server to read in the bytes and store them into database.
Below is my Java function (it is not tested yet since I don't have a way to read bytes yet) that I want to use to send the bytes. But I have no idea how to read them in on website side. Any suggestions would be appreciated. If you guys see that I'm doing something wrong also it would be appreciated if you let me know and tell me how I should fix it. Please be specific since I'm really new to this and don't really know much about web pages. Thanks.
private void sendImagesToServer() throws Exception
{
ImageItem image;
HttpURLConnection conn = null;
ImageIterator iterator;
DataOutputStream dos;
byte[] byteArray;
iterator = new ImageIterator(imageAdapter);
String uploadUrl;
while(iterator.hasNext())
{
image = iterator.getNext();
Uri uri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, Integer.toString(image.id));
Bitmap bmp=BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byteArray = stream.toByteArray();
uploadUrl = "http://localhost:63776/SQLScript.aspx";
// Send request
try {
// Configure connection
URL url = new URL(uploadUrl);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setRequestMethod("PUT");
conn.setRequestProperty("Connection", "Keep-Alive");
dos = new DataOutputStream(conn.getOutputStream());
dos.write(byteArray, 0, byteArray.length);
dos.flush();
dos.close();
// Read response
try {
if (conn.getResponseCode() == 200) {
Toast.makeText(this,"Yay, We Got 200 as Response Code",Toast.LENGTH_SHORT).show();
}
} catch (IOException ioex) {
ioex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
} finally{
}
}
}
If you've verified the bytes are getting out of the Java fine, check this question, it may have what you need.
Read Http Request into Byte array
As far as getting it into a database, you could save files in a binary database (different MSSQL setup) or convert to strings and back again as necessary.

getting bytes format in java of an image

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.

Categories