How to check if the bitmap has data? - android

What I have: I am downloading an image from a URL and converting it to a bitmap.
What is happening: Sometimes the server returns an image, other times just a small placeholder.
What I am trying to do: How to find out if the bitmap contains an image (the image is quite medium sized compared to the placeholder which is tiny).
Code used to get the image from the URL:
private Bitmap getBitmap(String url)
{
File f=fileCache.getFile(url);
//from SD cache
Bitmap b = decodeFile(f);
if(b!=null)
return b;
//from web
try {
Bitmap bitmap=null;
URL imageUrl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is=conn.getInputStream();
OutputStream os = new FileOutputStream(f);
Utils.CopyStream(is, os);
os.close();
bitmap = decodeFile(f);
return bitmap;
} catch (Exception ex){
ex.printStackTrace();
return null;
}
}

Determinate minimum width and height of image and if bitmap height and width is smaller than this minimum, it means that is placeholder. For example
Bitmap bitmap = decodeFile(f);
int minHeight = 500;
int minWidth = 500;
if(bitmap.getHeight() < minHeight && bitmap.getWidth() < minWidth){
//it is a placeholder
}

if the placeholder is the same size every time then just replace 60 with it's height in pixels. This just takes a Bitmap and returns true if the Bitmap height matches your placeholder.
private bool isPlaceholder (Bitmap bmp)
{
//presumably, the placeholder never changes size
//if it's 60 then we've got a placeholder
if (bmp.Height == 60){
return true;
}
else{
return false;
}
}
EDIT: This only works if the placeholder is always smaller than the image. Otherwise you would perhaps need more complex logic like checking the height and size of the image in bytes. OR Height and Width. If it's always smaller in height then you can use something like above.

Related

load many makers google map

hey I customize google map makers as an image in my android app , it's working fine but currently it takes time to load markers since there are many markers around 200. Actually, i get the images from backend (parse.com) and then crop it to fit marker shape.
Is there any way to load markers faster?
View marker2 = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.marker, null);
ImageView numTxt = (ImageView) marker2.findViewById(R.id.num_txt);
Bitmap bitmap1 = getBitmap(url1, MapActivity.this);
numTxt.setImageBitmap(bitmap1);
markerOpts = markerOpts.title("Company").snippet("branch").icon(BitmapDescriptorFactory.fromBitmap(createDrawableFromView(MapActivity.this, marker2)));
public static Bitmap getBitmap(String url2, Context context) {
FileCache fileCache = new FileCache(context);
MemoryCache memoryCache = new MemoryCache();
File f = fileCache.getFile(url2);
//from SD cache
//CHECK : if trying to decode file which not exist in cache return null
Bitmap b = decodeFile(f);
if (b != null)
return b;
// Download image file from web
try {
Bitmap bitmap = null;
URL imageUrl = new URL(url2);
HttpURLConnection conn = (HttpURLConnection) imageUrl.openConnection();
conn.setConnectTimeout(30000);
conn.setReadTimeout(30000);
conn.setInstanceFollowRedirects(true);
InputStream is = conn.getInputStream();
// Constructs a new FileOutputStream that writes to file
// if file not exist then it will create file
OutputStream os = new FileOutputStream(f);
// See Utils class CopyStream method
// It will each pixel from input stream and
// write pixels to output stream (file)
Utils.CopyStream(is, os);
os.close();
conn.disconnect();
//Now file created and going to resize file with defined height
// Decodes image and scales it to reduce memory consumption
b = decodeFile(f);
return bitmap;
} catch (Throwable ex) {
ex.printStackTrace();
if (ex instanceof OutOfMemoryError)
memoryCache.clear();
return null;
}
}
public static Bitmap createDrawableFromView(Context context, View view) {
DisplayMetrics displayMetrics = new DisplayMetrics();
((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
view.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
view.measure(displayMetrics.widthPixels, displayMetrics.heightPixels);
view.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
Yes, there is. You know for sure that you will need the pictures, so do that in an un-obtrusive way. Load them in the background once, while initializing. After you have loaded them once, just use them from your local environment. So, improvements:
request the pictures and parse them in a background thread while initializing the software to not bother the user with it
store the pictures when you have successfully extracted them and reuse them locally instead of rerequesting them
You can use image downloading library Picasso.
It will handle image downloading and caching, memory usage, and you can crop an image to whatever size you need. And if you load the same image many times (what you probably do) Picasso will use cached image instead of downloading it every time, so that will speed up all the images downloading process.
To use this library you need to declare it in dependency tree of build.gradle file from app folder of your project in Android Studio, so it will look like this:
dependencies {
//some other dependencies
//...
compile 'com.squareup.picasso:picasso:2.5.2'//add this line
}
Then use it in code:
Picasso.with(MapActivity.this).load(url1).into(numTxt);

Image Scaling is not working properly

I am working on a complex UI design it is like circular wheel containing 10 icons in circular locus. i need to scale every icon as per the device resolution. Please have a look for specific code snippet:-
if (displayWidth<=241) {
bitmap = scaleBimtap(bitmap, 42, 39);
}else if (displayWidth<=320) {
bitmap = scaleBimtap(bitmap, 42, 39);
}else if (displayWidth<=480) {
bitmap = scaleBimtap(bitmap, 52, 44);
}else{
bitmap = scaleBimtap(bitmap, 52, 44);
}
HTC sensation is a 540X960 resolution device. So here is bitmap = scaleBimtap(bitmap, 52, 44); must be chosen in this case but this seems to be wrongly scaled and icons being displayed bigger then. What can i do for this to work.
Image from URL
imageView = new (ImageView)findViewById(R.id.myImage);
Get Image from Url
Bitmap originalBitmap = getBitmapFromURL("http://www.chennaionline.com/home.JPG");
getBitmapFromURL method:
public static Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Set bitmap
Bitmap bitmap = Bitmap.createScaledBitmap(originalBitmap, width,
height, false);
imageView.setImageBitmap(bitmap);
Image from Resource File
Bitmap bitmap = ((BitmapDrawable)imageView.getDrawable()).getBitmap();

scaled image not visible in android

I have to make an application in which i am downloading an image from a URL and i have to show the image to after scaling.
The default size of the image is 220x200
Scaled size of image is 55x50
Here is my code for doing the above:
XML file layout:
<ImageView android:id="#+id/productimage"
android:layout_gravity="center_vertical|left" android:layout_width="55dip"
android:layout_height="50dip" android:adjustViewBounds="true" />
Here is the code for downloading the image and resizing it:
ImageView productImage = (ImageView) arg1
.findViewById(R.id.productimage);
if (!headerDetails[1].equals("null")) {
Bitmap image = getImage(headerDetails[1]);
if (image != null) {
try {
productImage
.setImageBitmap(Bitmap
.createScaledBitmap(
image,
productImage
.getMeasuredWidth(),
productImage
.getMeasuredHeight(),
false));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Here is the class for downloading the image:
private Bitmap getImage(String address) {
try {
Log.i("getimage", address);
URL url = new URL(address);
URLConnection conn = url.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
Bitmap bm = BitmapFactory.decodeStream(bis);
// bis.close();
// is.close();
return bm;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
No exception is being thrown here, hence the image is being downloaded correctly.
OUTPUT: No image is displayed in the imageview.
what am i doing wrong. The size of the image that i want is 55x50 but the size of the image on the net may vary.
thank you in advance.
EDIT:
the bitmap formed after the following code:
Bitmap bm = BitmapFactory.decodeStream(bis);
does not have a height and a width and it's height and width is set to -1. What could be going wrong here?
The following exception is also being thrown:
06-23 14:24:41.635: WARN/System.err(16618): java.lang.IllegalArgumentException: width and height must be > 0
I used this code to scale the bitmap:
Bitmap selectedImage = BitmapFactory.decodeFile(selectedImagePath);
image.setImageBitmap(Bitmap.createScaledBitmap(selectedImage,75, 75, true));
Try adding android:scaleType="fix_xy" to the imageview. Another error I found in your code is that you are getting the height and width in a wrong way. Try this:
imageView.getLayoutParams().height;
imageView.getLayoutParams().width;

Load Large Image from server on Android

I am trying to display a jpg file from a server into an imageView. When I try to load a smaller image (300x400), there are no problems. But when I try to load a full size picture (2336x3504), the image will not load. The file size of the image is only 2mb. I do not get any errors in logcat and there are no exceptions thrown. It simply won't load the image. I also tried using this:
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap=BitmapFactory.decodeStream(is,null,options);
This doesn't do anything to help load the large files, but it does resize the smaller image (like it is suppose to). I did add the large picture to my resources and tested it as if it was embedded in the app and it worked fine, just won't work on the server. I have been working all day on this and can't seem to figure out how to load these large pictures. Can anyone help me out with this? Thanks for any info.
Here is the link where I found the above code and have been playing with the other examples but still not getting it to work.
EDIT:
Here is the code I'm using, to load the image:
public static Bitmap getBitmapFromURL(String src) {
Bitmap bmImg;
URL myFileUrl = null;
try {
myFileUrl = new URL(src);
HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
BitmapFactory.Options options=new BitmapFactory.Options();
options.inSampleSize = 16;
bmImg = BitmapFactory.decodeStream(is, null, options);
return bmImg;
} catch (Exception e) {
// TODO Auto-generated catch block
Log.d("Error", e.toString());
return null;
}
}
Here is the logcat screenshot (couldn't figure out how to copy the text appropriately in eclipse) I cleared the log right before I hit the button to load the image. So all you see is what happens when I hit that button. I erased the company and app names (where you see "com.", assume its "com.mycompany.myapp".
It is not uncommon for BitmapFactory.decodeFromStream() to give up and just return null when you connect it directly to the InputStream of a remote connection. Internally, if you did not provide a BufferedInputStream to the method, it will wrap the supplied stream in one with a buffer size of 16384. One option that sometimes works is to pass a BufferedInputStream with a larger buffer size like:
BufferedInputStream bis = new BufferedInputStream(is, 32 * 1024);
A more universally effective method is to download the file completely first, and then decode the data like this:
InputStream is = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is, 8190);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte)current);
}
byte[] imageData = baf.toByteArray();
BitmapFactory.decodeByteArray(imageData, 0, imageData.length);
FYI, the buffer sizes in this example are somewhat arbitrary. As has been said in other answers, it's a fantastic idea not to keep an image that size in memory longer than you have to. You might consider writing it directly to a file and displaying a downsampled version.
Hope that helps!
Devunwired's answer is right but out of memory error can occur if image size is too large, in that case we will have to scale down image, here is the code to scale down image after DevunWired's download image code
final BitmapFactory.Options options = new BitmapFactory.Options();
BufferedInputStream bis = new BufferedInputStream(is, 4*1024);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte)current);
}
byte[] imageData = baf.toByteArray();
BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);
options.inJustDecodeBounds = true;
options.inSampleSize = 2; //calculateInSampleSize(options, 128, 128);
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeByteArray(imageData, 0, imageData.length, options);
Does it silently fail, or does it throw an exception or OutOfMemory error? Btw, if a jpeg is 2MB that doesn't mean it'll take up 2MB of memory. 2MB is the compressed size, and since Android is working with a Bitmap, the 2336 x 3504 will take up approximately 2336 x 3504 x 4 bytes in memory. (2336 x 3504 x 4 = 32,741,376). Downsampling 8 times still might not be enough, especially if you have other bitmaps in memory at the time.

How to set a bitmap from resource

This seems simple, I am trying to set a bitmap image but from the resources, I have within the application in the drawable folder.
bm = BitmapFactory.decodeResource(null, R.id.image);
Is this correct?
Assuming you are calling this in an Activity class
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.image);
The first parameter, Resources, is required. It is normally obtainable in any Context (and subclasses like Activity).
Try this
This is from sdcard
ImageView image = (ImageView) findViewById(R.id.test_image);
Bitmap bMap = BitmapFactory.decodeFile("/sdcard/test2.png");
image.setImageBitmap(bMap);
This is from resources
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.icon);
If the resource is showing and is a view, you can also capture it. Like a screenshot:
View rootView = ((View) findViewById(R.id.yourView)).getRootView();
rootView.setDrawingCacheEnabled(true);
rootView.layout(0, 0, rootView.getWidth(), rootView.getHeight());
rootView.buildDrawingCache();
Bitmap bm = Bitmap.createBitmap(rootView.getDrawingCache());
rootView.setDrawingCacheEnabled(false);
This actually grabs the whole layout but you can alter as you wish.
If you have declare a bitmap object and you want to display it or store this bitmap object. but first you have to assign any image , and you may use the button click event, this code will only demonstrate that how to store the drawable image in bitmap Object.
Bitmap contact_pic = BitmapFactory.decodeResource(
v.getContext().getResources(),
R.drawable.android_logo
);
Now you can use this bitmap object, whether you want to store it, or to use it in google maps while drawing a pic on fixed latitude and longitude, or to use some where else
just replace this line
bm = BitmapFactory.decodeResource(null, R.id.image);
with
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.YourImageName);
I mean to say just change null value with getResources() If you use this code in any button or Image view click event just append getApplicationContext() before getResources()..
Using this function you can get Image Bitmap. Just pass image url
public Bitmap getBitmapFromURL(String strURL) {
try {
URL url = new URL(strURL);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}

Categories

Resources