I used the code from this answer, and compiled everything successfully.
However, I cannot find out how to use the drawable that I have just created. Here is my code:
Drawable dr2 = getResources().getDrawable(android.R.drawable.ic_menu_manage);
Bitmap bitmap2 = ((BitmapDrawable) dr2).getBitmap();
Drawable f = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap2, 256, 256, true));
private Integer[] menu_icon = {
android.R.drawable.f,
// I can't figure out how to call Drawable f
};
After converting the drawable to the Drawable f, I am unable to find out how to recall the resized drawable. I have tried using all possible locations in my code as to where it may be (/res/drawable and a few other locations). However, I am unable to compile no matter how I try to call Drawable f. Any help would be greatly appreciated!
(And no, I have eight elements in that array, but only copy+pasted one)
It exists only in memory, not anywhere on disk. You can't reference it by id. Instead, you need to call versions of functions that take a Drawable rather than ones that take an int resourceID.
Related
I showed a photo on the map using the osmdroid and first methods.
Now I want to read a jpeg format picture from the device memory and show it as a bitmap on the map. The code does not give an error. But the photo is not displayed. please guide me. The following are the first and second method codes.
/// first method
GroundOverlay myGroundOverlay = new GroundOverlay();
myGroundOverlay.setPosition(overlayCenterPoint);
Drawable d = ResourcesCompat.getDrawable(getResources(), R.mipmap.ic_imageonmap_test2, null);
myGroundOverlay.setImage(d.mutate());
//myGroundOverlay.setImageBitmap(bitmap);
myGroundOverlay.setDimensions(2000000.0f);
myGroundOverlay.setTransparency(0.25f);
myGroundOverlay.setBearing(0);
mMapView.getOverlays().add(myGroundOverlay);
mMapView.invalidate();
////// second method
Bitmap src = BitmapFactory.decodeFile("/sdcard/osmdroid/20190722033213_1440103389.jpg");
Bitmap bitmap2 = src.copy(Bitmap.Config.ARGB_8888, true);
GroundOverlay myGroundOverlay2 = new GroundOverlay();
myGroundOverlay2.setPosition(overlayCenterPoint);
//myGroundOverlay2.setImageBitmap(src);
myGroundOverlay2.setImageBitmap(bitmap2);
//myGroundOverlay2.setDimensions(2000.0f);
//myGroundOverlay2.setTransparency(0.25f);
myGroundOverlay2.setBearing(0);
mMapView.getOverlays().add(myGroundOverlay2);
mMapView.invalidate();
I assume you are using OSMBonusPack GroundOverlay.
Your code in method 1 seems correct (even if dimension seems huge).
In method 2, setDimensions is missing.
Did you try the OSMBonusPack tutorial "as is" (same position/dimension, same bitmap from resources)?
Also, try: "setBearing(0.0f);" (I'm not confident about implicit cast from int to float)
final Bitmap b = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
I am getting a null references error.
B is null.
Why is that?
Good question i went in the exact same issue (with the exact same file :)
It seems that
BitmapFactory.decodeResource works quite perfect with R.drawable and R.raw but not with mipmaps probably caused by the different screen resolutions, but this is just a guess.
Looking in the source i can only see that decodeResource calls Resource#openRawResource(..) and the documentation says:
... asset file -- that is, it can be used to open drawable, sound, and
raw resources;it will fail on string and color resources.
i guess mipmap files are not considered as raw resources as there is additional handling for choosing density dependent resources.
So you will have to specify the density of the resource: https://stackoverflow.com/a/41910618/8524651
Or quick and dirty just move a copy of that file to your raw folder.
The solution code in kotlin (decide for one way ;)
val launcherDrawable = ResourcesCompat.getDrawableForDensity(context.resources, R.mipmap.ic_launcher, DisplayMetrics.DENSITY_LOW, context.getTheme());
var bm = BitmapFactory.decodeResource(context.resources, R.raw.ic_launcher)
bm = launcherDrawable!!.toBitmap(launcherDrawable.minimumWidth, launcherDrawable.minimumHeight)
This may help you
Drawable d = getResources().getDrawable(R.mipmap.imagefile);
Bitmap b = ((BitmapDrawable)d).getBitmap();
Can someone give such a code or at least an idea how to make such wallpapers.
I guess I got to use Vieflipper but I cant use Random with this. Am I right? Thanks.
Your question looks a bit unspecific. In any case, to put it simple, let's assume you have an ImageView that you want to change dynamically in a random manner. The structure should look something like this:
imv = (ImageView)findViewById(R.id.imageView1);
Resources rsrc= getResources();
imid = R.drawable.yourimagename;
Drawable drawable= rsrc.getDrawable(imid);
Bitmap bm = BitmapFactory.decodeResource(rsrc,drawable);
imv.setImageBitmap(bm);
In this example, imid is hardcoded, but you could easily change it dinamically. For instance, create an array list of integers containing your desired images ids and then access them in a loop or whenever a condition is met (for instance every 30 seconds).
Eg:
ArrayList<Integer> listofimagesids = new ArrayList<Integer>;
listofimagesids.add(R.drawable.yourimagename1)
listofimagesids.add(R.drawable.yourimagename2)
...
listofimagesids.add(R.drawable.yourimagenameN)
Random rand = new Random();
if (youcondition){
int n = rand.nextInt(listofimagesids.size());
Drawable drawable= rsrc.getDrawable(n);
Bitmap bm = BitmapFactory.decodeResource(rsrc,drawable);
imv.setImageBitmap(bm);
}
Of course this is just pseudo-code, but it might guide you a bit. Hope it helps.
I'm having trouble cloning a BitmapDrawable. I tried the answer in this post but it creates a "shallow" copy, and I need a "deep" copy so I can alter the pixels in the clone without affecting the original.
I also tried this:
Bitmap bitmap = bdOriginal.getBitmap();
BitmapDrawable bdClone = new BitmapDrawable(getResources(), bitmap.copy(bitmap.getConfig(), true));
But it seems to create an immutable clone even though I set the mutable parameter in Bitmap.copy() to "true". That is, color filters don't appear to change the clone. Am I doing it wrong? (EDIT: I used the debugger to confirm bitmap.mIsMutable = true)
To summarize, I need a clone of a BitmapDrawable that can be altered with color filters without affecting the original. Any suggestions?
Thanks in advance...
Create new Bitmap of the same size.
Create canvas for this new Bitmap
Draw your first Bitmap into this canvas.
Example:
Bitmap copy = Bitmap.createBitmap(original.getWidth(), original.getHeight(), original.getConfig());
Canvas copiedCanvas = new Canvas(copy);
copiedCanvas.drawBitmap(original, 0f, 0f, null);
I like to use the assets folder instead of the drawable folder (if it's not a nine-patch) because I can use multiple folders there. However the method I use to get an drawable required the cpu to do quiet a lot. For example: after adding 10 ImageViews need 10% CPU (I am using Android Assistent and Samsung TouchWiz TaskManager). I haven't notice it while I was writing a game. And now this game needs 40-100% CPU even if it isn't in the foreground.
That's the method I use to create an drawable:
public BitmapDrawable readAsset(path){
try{
inputStream = assetManager.open(path);
//get the Bitmap
desiredImg = BitmapFactory.decodeStream(inputStream, null, opts);
//resize for other screen sizes (scale is calculated beforehand)
scaleX =(int)(desiredImg.getWidth()/scale);
scaleY = (int)(desiredImg.getHeight()/scale);
//Bitmap to get config ARGB_8888 (createScaledBitmap returns RGB_565 => bad quality especially in gradients)
//create empty bitmap with Config.ARGB_8888 with the needed size for drawable
Bitmap temp = Bitmap.createBitmap(scaleX, scaleY, Config.ARGB_8888);
//Canvas to draw desiredImg on temp
Canvas canvas = new Canvas(temp);
canvas.drawBitmap(convert, null, new Rect(0, 0, scaleX, scaleY), paint);
//Convert to BitmapDrawable
BitmapDrawable bitmapDrawable=new BitmapDrawable(temp);
bitmapDrawable.setTargetDensity(metrics);
inputStream.close();
return bitmapDrawable;
}catch (Exception e) {
Log.d(TAG, "InputStream failed: "+e.getMessage());
}
return null;
}
The only thing I do in the app is adding some ImageViews in a RelativeLayout with this method:
private void addImageToContainer(int paddingLeft, int paddingTop) {
ImageView imageView = new ImageView(this);
imageView.setImageDrawable(assetReader.readAsset("test.jpg"));
imageView.setPadding(paddingLeft, paddingTop, 0, 0);
container.addView(imageView);
}
Probably the best thing for you to do would be to profile the execution with traceview, as this will give you a full understanding of where your app is spending most of its execution time. Then you can focus on optimizing that specific piece of code.
Just an educated guess, but I have a feeling that the majority of the wasted execution is not because you are pulling the images out of assets/ instead of resources, but all the scaling work being done afterwards (and from the looks of it, this is all being done on the main thread, so there's no concurrency to speak of).
I might recommend trying to leverage some of the BitmapFactory.Options (Docs link) available to you when you decode the asset. In particular, you should be able to do all the scaling you need with a combination of the inScaled, inDensity, and inTargetDensity options. If you pass these to your decodeStream() method, you could likely remove all the subsequent code used to resize the image before returning.