I've been trying to check if a ImageView has a bitmap on it and it's not working..
I tried
Bitmap bitmap = ((BitmapDrawable) IdFront.getDrawable()).getBitmap();
but it retunrs ""
and imageViewOne.getDrawable() == null
and finally :
private boolean hasImage(#NonNull ImageView view) {
Drawable drawable = view.getDrawable();
boolean hasImage = (drawable != null);
if (hasImage && (drawable instanceof BitmapDrawable)) {
hasImage = ((BitmapDrawable)drawable).getBitmap() != null;
}
return hasImage;
But the Bitmap returns "" and not null.
You could do like this:
ImageView view = findViewById(R.id.imageView);
view.setImageResource(R.drawable.sample);
BitmapDrawable drawable = (BitmapDrawable) view.getDrawable();
Bitmap bitmap = drawable.getBitmap();
If you want to know drawable or bitmap variable value when debugging, you could see
drawable.toString()
bitmap.toString()
like below fig:
Try like below:
boolean hasImage = (view.getDrawable() == null);
Related
I want to set loaded image as a background of a coordinator layout and apparently setImageBitmap() function allow only views like ImageView, textView etc to set loaded image as background. What should I do?
if (requestCode == REQUEST_CODE_SELECT_IMAGE && resultCode == RESULT_OK) {
if (data != null) {
Uri selectedBgImageUri = data.getData();
if (selectedBgImageUri != null) {
try {
InputStream inputStream = getContentResolver().openInputStream(selectedBgImageUri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
coordinatorLayout.setImageBitmap(bitmap);
selectedImagePath = getPathFromUri(selectedBgImageUri);
} catch (Exception exception) {
Toast.makeText(this, exception.getMessage(), Toast.LENGTH_SHORT).show();
}
}
}
}
You can use BitmapDrawable to perform that
InputStream inputStream = getContentResolver().openInputStream(selectedBgImageUri);
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
Resources resources = getResources();
// Or if you are in fragment
// Resources resources = requireContext().getResources();
Drawable drawable = new BitmapDrawable(resources, bitmap);
coordinatorLayout.setBackground(drawable);
I'm using Cardslib library. I was trying to add thumbnail view for each pacakge from its icon. Icon is Drawable type. So I assume, we need to use CustomSource to create a Bitmap of it. Then add it to the card.
The problem with the below code is, all packages gets same thumbnail image. (The image from last package appearing on the list). Is this due to cardslib loads them using the built-in AsyncTask and LRUCache. How to resolve this issue?
public void listpkg(Context c) {
ArrayList<Card> cards = new ArrayList<Card>();
Card card = new Card(this);
mContext = c;
CardHeader header = new CardHeader(c);
PackageManager pm = getPackageManager();
List<ApplicationInfo> packages = pm.getInstalledApplications(PackageManager.GET_META_DATA);
for (ApplicationInfo packageInfo : packages) {
header = new CardHeader(this);
header.setTitle(pm.getApplicationLabel(packageInfo).toString());
card = new Card(this);
card.addCardHeader(header);
card.setTitle("Package: " + packageInfo.packageName);
icon =getPackageManager().getApplicationIcon(packageInfo); //TODO use this icon
tagname = packageInfo.packageName;
// CustomSource --
thumb = new CardThumbnail(c);
thumb.setCustomSource(new CardThumbnail.CustomSource() {
#Override
public String getTag() {
return tagname;
}
#Override
public Bitmap getBitmap() {
PackageManager pm = mContext.getPackageManager();
Bitmap bitmap = null;
try {
bitmap = drawableToBitmap(pm.getApplicationIcon(getTag()));
} catch (PackageManager.NameNotFoundException e) {
}
return bitmap;
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
});
card.addCardThumbnail(thumb);
// CustomSource --
cards.add(card);
}
CardArrayRecyclerViewAdapter mCardArrayAdapter;
mCardArrayAdapter = new CardArrayRecyclerViewAdapter(this, cards);
//Staggered grid view
CardRecyclerView mRecyclerView = (CardRecyclerView) this.findViewById(R.id.mainListView);
mRecyclerView.setHasFixedSize(false);
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
//Set the empty view
if (mRecyclerView != null) {
mRecyclerView.setAdapter(mCardArrayAdapter);
}
}
xml
<it.gmariotti.cardslib.library.recyclerview.view.CardRecyclerView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:list_card_layout_resourceID="#layout/list_card_thumbnail_layout"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="12dp"
android:id="#+id/mainListView" />
Ok instead of keeping tagname to one variable and passing it to an inner implementation of CustomSource, you implement the CustomSource in another class and keep a field variable to hold the tagname. As in the current implementation the global (in this context) tagname is being replaced with each iteration.
class MyThumbnailSource implements CardThumbnail.CustomSource {
private String tagname;
public MyThumbnailSource(String tagname){
this.tagname = tagname;
}
#Override
public String getTag() {
return tagname;
}
#Override
public Bitmap getBitmap() {
PackageManager pm = mContext.getPackageManager();
Bitmap bitmap = null;
try {
bitmap = drawableToBitmap(pm.getApplicationIcon(getTag()));
} catch (PackageManager.NameNotFoundException e) {
}
return bitmap;
}
private Bitmap drawableToBitmap(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable) drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
}
and call it like : thumb.setCustomSource(new MyThumbnailSource(tagname));
I'm attempting to save all of the icons of the packages on a device as a BMP or PNG file by iterating through each package and doing the following.
Drawable icon = getPackageManager().getApplicationIcon(packageInfo);
Bitmap bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
try {
out = new FileOutputStream("/storage/sdcard0/images/" + packageInfo.packageName +".png");
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try{
out.close();
} catch(Throwable ignore) {}
}
This is creating blank images though, how would I change my code to create the actual icon in an image format?
My issue was this if anyone has the same problem, I referenced this answer.
I forgot to check to see if the icon was already an instance of BitmapDrawable. Because it was I could just cast it to a bitmapdrawable and use .getBitmap
if (icon instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable)icon).getBitmap();
}else{
bitmap = Bitmap.createBitmap(icon.getIntrinsicWidth(), icon.getIntrinsicHeight(), Config.ARGB_8888);
}
Below is the code that could cover all the cases.
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if (bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
return Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
return Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
}
I'm using the following code to create a resized bitmap, the code works okay, but it's very slow. The problem is that when I try to use this for more than one image the phone freezes until the images are created.
Here is my code:
Bitmap bitmap = null;
File imgFile = new File(my_pic_file);
if(imgFile.exists()) {
bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
Bitmap resizedBitmap = Bitmap.createScaledBitmap(bitmap, 300, 200, false);
first_image.setImageBitmap(resizedBitmap);
}
The problem is that you are doing the work on the main thread. This means that it will freeze the UI until all the processing is finished. You can fix this by either using a thread or asynchronous task.
private class LoadImageTask extends AsyncTask<String, Void, Bitamp> {
private ImageView mImageView = null;
public LoadImageTask(ImageView imageView) {
mImageView = imageView;
}
protected Bitmap doInBackground(String... file) {
Bitmap bitmap = null;
Bitmap resizedBitmap = null;
File imgFile = new File(file);
if(imgFile.exists()) {
bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
resizedBitmap = Bitmap.createScaledBitmap(bitmap, 300, 200, false);
}
return resizedBitmap;
}
protected void onPostExecute(Bitmap result) {
if (result != null && mImageView != null) {
mImageView.setImageBitmap(result);
}
}
Then in your code just call
new LoadImageTask(first_image).execute(my_pic_file);
I want to set the image res/drawable-hdpi/nasa_image.jpg as the wallpaper.
I wrote the following code but it raises the FileNotFoundException.
Uri u1 = Uri.fromFile(new File("res/drawable-hdpi/nasa_image.jpg"));
Uri u2 = Uri.parse("android.resource://com.my.package/drawable/nasa_image.jpg");
Uri u3 = Uri.parse("android.resource://com.my.package/" + R.drawable.nasa_image);
WallpaperManager w = WallpaperManager.getInstance(this);
Bitmap bitmap;
try {
bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(u));
w.setBitmap(bitmap);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
First I tried for u1. It didn't work. Then I searched and found this. I then tried u2 and u3.
I checked the log. Every time it gave the same FileNotFoundException.
How to refer to it? Where am I wrong? Am I taking the wrong root directory?
I think this is a wrong way to do that in android. why don't you use the resource identifier?
ImageView imgView=(ImageView)findViewById(R.id.imageView1);
int id = getResources().getIdentifier(nasa_image, "drawable", getPackageName());
Drawable drawable=res.getDrawable(id);
imgView.setImageDrawable(drawable);
or
ImageView imgView=(ImageView)findViewById(R.id.imageView1);
Drawable drawable= getResources().getDrawable(R.drawable.nasa_image);
imgView.setImageDrawable(drawable);
imgView.setImageDrawable();
Update to convert from drawable to bitmap just use this (assuming that your drawable is an instanceof Bitmapdrawable)
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
Use this method if you are not sure about drawable instance
public static Bitmap drawableToBitmap (Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return ((BitmapDrawable)drawable).getBitmap();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
Use this method if you are sure that you the right file path
private Drawable getDrawable(String path) {
File imgFile = new File(path);
if (imgFile.exists()) {
Bitmap bitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
return new BitmapDrawable(resources, bitmap);
}
return null;
}
you can adjust it to return bitmap or drawable according to your issue
You should not include the extention (.jpg)
Use:
Uri.parse("android.resource://" + BuildConfig.APPLICATION_ID + "/drawable/nasa_image");
Try
Uri u1 = Uri.parse("R.drawable.nasa_image");