Is there any way to get the image dimensions or size without actually downloading it from the server.
Like if a image is hosted on https://500px.com/
or https://imgur.com/ and i want to do some calculations but i also want to save the bandwidth. If the image size is quite large and the user bandwidth is not so good i want to queue the image for later.
Assuming that API doesn't provide such information.
In the didRecieveResponse delegate method for the NSURLConnection you will recieve a response that contains such info. if and only if those has been set on server:
The following gets you the disk size of the image:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
int state = [httpResponse statusCode];
if (state >= 400 && state <600)
{
// something wrong happen
}
NSLog(#"Download Response : %#", [response description]); // this shows all the info. available by server.
int file_size = [response expectedContentLength];
}
You can check for the size and then cancel the connection if you want to.
For image dimensions. check this question. the answer claims that
it can be done with the suggested fastimage category.
The only logical way to get this done is by downloading the first part of the image that contains the image header. which contains such an info as the image type(png, jpg ...) and the image dimensions. I believe that this library do so.
I don't know if it's possible or not. But here is my tip. you could check the size of the file. see here: How to know the size of a file before downloading it?
and if the size is larger than x you queue the image for later ;-)
Code from linked answer:
URL url = new URL("http://server.com/file.mp3");
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int file_size = urlConnection.getContentLength();
It's not possible to calculate image size without downloading.
Related
I'm trying to create a Google drive android app where I should be able to download resized images from Google drive.
It's kind of a performance issue.
Suppose I have uploaded an image of 1080px from my computer, now I wish to download that image to my Android phone which doesn't support 1080px image, so what happens is the image first gets downloaded then it's resized as per my device dimensions. But this is actually wastage of time and data.
Why to download a 1080px image when I can only show may be like 480px or 720px image.
I'm using Google drive api but I would like to know whether there is some parameter or something which we can pass from phone so that we get to download the resized image only.
As per my search,
Link
There is this Partial download where I can give a range of bytes but I'm not trying to download a particular portion of a file, I want to download the whole image file in a resized format.
Any ideas, clues will be very helpful.
Thanks
The answer applies to the RESTful Api, since GDAA does not have a 'thumbnailLink' functionality as of today (Feb 14. 2015).
I use this code snippet to download reduced images and thumbnails:
/**
* get file contents, specifically image. The thmbSz, if not zero, it attempts to
* retrieve an image thumbnail that fits into a square envelope of thmbSz pixels
* #param rsId file id
* #param thmbSz reduced size envelope (optional value, 0 means full size image / file)
* (tested with: 128,220,320,400,512,640,720,800,1024,1280,1440,1600)
* #return file's content / null on fail
*/
com.google.api.services.drive.Drive mGOOSvc;
...
static byte[] read(String rsId, int thmbSz) {
byte[] buf = null;
if (rsId != null) try {
File gFl = (thmbSz == 0) ?
mGOOSvc.files().get(rsId).setFields("downloadUrl").execute() :
mGOOSvc.files().get(rsId).setFields("thumbnailLink").execute();
if (gFl != null){
String strUrl;
if (thmbSz == 0)
strUrl = gFl.getDownloadUrl();
else {
strUrl = gFl.getThumbnailLink();
if (! strUrl.endsWith("s220")) return null; //--- OOPS ------------>>>
strUrl = strUrl.substring(0, strUrl.length()-3) + Integer.toString(thmbSz);
}
InputStream is = mGOOSvc.getRequestFactory()
.buildGetRequest(new GenericUrl(strUrl)).execute().getContent();
buf = UT.is2Bytes(is);
}
} catch (Exception e) { UT.le(e); }
return buf;
}
I have a tested it with a few sizes (see the method header), which I snatched from Picasa documentation here.
See, the 'thumbnailLink' has the form of
https://lh4.googleusercontent.com/R1Pi...blahblah...08qIhg=s220
and by changing the '220' at the end to one of these values:
128,220,320,400,512,640,720,800,1024,1280,1440,1600
I managed to pull the image of the requested size (letting the server to reduce it).
DISCLAIMER:
It is not a documented feature, so it is a HACK. I also admit that a more robust version should not rely on finding "s220", but probably "=sNUMBER" patttern.
Good luck.
I have read that HttpUrlConnection sends GET request when connection is made. Also then I can retrieve an instance of InputStream to read that resource. Does this mean that whole resource file is downloaded as the connection is made?
What I want to achieve is to set an ImageView image to remote image from the web. However my idea is to do this in memory-friendly way and calculate inSampleSize for BitmapFactory. In order to calculate that size - I need view dimensions and remote image dimensions. Remote image dimensions may be retrieved this vay (basically it should not load an image into memory):
BitmapFactory.Options options = new BitmapFactory.Options ();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream (inputStream, null, options);
However once read inputStream can not be reused in this case (or can it?). Also HttpUrlConnection returns the same instance of InputStream which means that if I want to read an image again (and load only the size I need using inSampleSize option) - I have to re-connect.
I want to be able to load large images, however as I have heard - HTTP requests are slow so is it worth it to send a second request? Also I don't know if the whole image is downloaded anyway even if I am reading only image info for the first time and not loading the whole thing.
If it is not worth it I think the only way will be to copy whole image into memory, get it's dimensions, read only the size I need and finally clean up the memory. Witch would be pretty memory expensive for the short period of time.
For loading images from remote web use Android Smart Image View..
it Load Images from URLs in memory friendly way
http://loopj.com/android-smart-image-view/
Using this code:
Picasso.with(context).load(url).resize(60, 60)
Does Picasso resize the image before it is downloaded? If the image was 8MB - I wouldn't want it to be downloaded then resized.
I couldnt find the answer anywhere but maybe it is obvious!
No, obviously it doesn't resize it before downloading - it's impossible. Look at the chaining, first - download, second - resizing. If you want to get a smaller images, you should ask for a smaller images if you have such a chance, of course. You can write graceful degradation: if the file size is bigger than limit, then just don't download it and display some placeholder instead. It can be implemented by checking content length at first:
URL url = new URL("http://server.com/file.png");
URLConnection urlConnection = url.openConnection();
urlConnection.connect();
int file_size = urlConnection.getContentLength();
Taken from here How to know the size of a file before downloading it?
This question already has answers here:
Get the image as Thumbnail
(2 answers)
Closed 9 years ago.
My app is currently sending images from an Android device to a PHP script by converting the image into a bit array and then converting to base64. The base64 string is then sent in a HTTP request.
The problem is that is the image is big (like the ones taken from android camera) then the transfer fails. What i want to do is change the image size before it goes through the conversion process.
How can i do this? I've tried to google it but have had no luck so far.
If your image size is big then you have to need first scale in to small size then encode this by base64 class then you send this on your server.
For scale your image read this http://developer.sonymobile.com/2011/06/27/how-to-scale-images-for-your-android-application
or other post
Use jpeg compression!
('Cause I'm not sure how sending up a base64 encoded byte array is going to save you any space.)
May I jump in and assume you've got a stage where you've converted your image into an array of pixels instead? If not, I'll assume there is no reason why the obvious conversion from bytes to integers representing pixels applies. Then we'll convert it to a compressed jpeg.
final int[] pixels = yourpixels;
You'll also need width and height:
final int width = theWidth; etc...
Next, get hold of your output stream in your client:
final HttpURLConnection connection = doWhateverYouDoToOpenYourConnection();
final OutputStream httpOutputStream = connection.getOutputStream();
Now the crucial step is to use the compression methods of Android's bitmap library to stream the compressed image onto the http output stream:
final Bitmap androidBitmap = Bitmap.createBitmap(pixels, width, height,Config.ARGB_8888);
androidBitmap.compress(android.graphics.Bitmap.CompressFormat.JPEG, YOUR_QUALITY_INT, outputStream);
Start with something like YOUR_QUALITY_INT = 85 to see significant improvement in image size without much visible deformation.
If this fails, create a scaled bitmap from a scale matrix: documentation here. This reduces the width and height of your bitmap on creation, which obviously reduces request size.
Hope this helps.
I guess this quesiton has been answered already, buy it doesn't seem to work, and it is very furstrating...
I am just trying to get the size of a remote file in Android.
So far, I have tried the following two approaches, without success:
1)
try
{
file = new File("http://50.19.156.118/feed2/storage/download/a_17/Madagascar.3gp");
a=(int) myFileBeingUploaded.length();
}
catch (Exception j)
{
}
2)
try
{
url = new URL("http://50.19.156.118/feed2/storage/download/a_17/Madagascar.3gp);
urlConnection = (HttpURLConnection) url.openConnection();
a=urlConnection.getContentLength();
}
catch (Exception e)
{
}
getContentLength() returns always 77 !!, while File.length() returns 0
Any ideas?
Many thanks
HTTP is not a filesystem -- it is a protocol for communicating hyperlinked resources. With standard HTTP, the only way to determine the size of a resource is to download that resource. The way to solve your problem, assuming that you want the size before you want the resource, is to implement another resource which tells you the size. True, the Content-Size field of a response tells you the size of the data contained in the response, but only after you request the resource.
e.g. given your web server with image portrait.jpg, you could set up a php script meta.php to which you pass the name of the resource of interest... meta.php?f=portrait.jpg. Then meta.php would ask its filesystem for the size of f and return that number via HTTP.