I have a bitmap downloader class which decodes a stream into a Bitmap object.
Can I do something like
Bitmap bitmap;
bitmap = object;
when I do imageview.setImageBitmap(bitmap)
would be the same as imageview.setImageBitmap(object)
Also, is it posible to create multiple instances of bitmap? like:
for(i = 0; i < 10; i++) {
Bitmap bitmap = new Bitmap(); // how to do this?
new BitmapDownloaderAsynctask(bitmap).execute(url);
}
when I do imageview.setImageBitmap(bitmap) would be the same as imageview.setImageBitmap(object)
Yes, it would be the same (as long as object is another instance of Bitmap)
In order to create Bitmap manually, there is a bunch of static methods Bitmap.createBitmap() exist to create bitmaps (Bitmap class)
As an example, here is the easiest way to create a bitmap:
Bitmap bmp = Bitmap.createBitmap(100, 100, Config.ARGB_8888); //100*100 bitmap in ARGB color space
EDIT:
If you need to keep bitmap reference unchanged, you need to decode stream in a separate bitmap and then copy content of this bitmap into your original bitmapHolder. You can do that by drawing on the canvas:
AsyncTask code:
.....
Canvas canvas = new Canvas(bitmapHolder); //this bitmap was passed to AsyncTask
Bitmap tmpBitmap = Bitmap.decodeStream(...);
canvas.drawBitmap(tmpBitmap, 0, 0, null); //this will copy your decoded bitmap into your original bitmap which was passed into AsyncTask
.....
Related
I'm trying to create a canvas from a PNG file that I have loaded into a bitmap, but it gives an error. Here's the code:
public Bitmap CABINET_Bitmap;
AssetManager assetManager = this.getAssets();
inputStream = assetManager.open("background.png");
CABINET_Bitmap = BitmapFactory.decodeStream(inputStream);
// Next line gives error
Canvas cv = new Canvas(CABINET_Bitmap);
If I create the bitmap, rather than load it in, by doing:
CABINET_Bitmap = Bitmap.createBitmap(480, 640, Config.RGB_565);
Canvas cv = new Canvas(CABINET_Bitmap);
Then the canvas creation works. Any ideas what I'm doing wrong?
The documentation states:
Construct a canvas with the specified bitmap to draw into. The bitmap
must be mutable.
The initial target density of the canvas is the same as the given
bitmap's density.
So what I'm assuming is BitmapFactory.decodeStream() is returning an immutable bitmap while Bitmap.createBitmap() is return a mutable one. Instead, use BitmapFactory.Options and set inMutable to true.
BitmapFactory.Options o = new BitmapFactory.Options();
o.inMutable = true;
CABINET_Bitmap = BitmapFactory.decodeStream(inputStream, o);
Canvas cv = new Canvas(CABINET_Bitmap);
See if that works.
I'm trying to draw some addition to my ImageView's content, which is represented by Drawable from resources. I know that all Drawables from resources are immutable by default, but even after I call mutable() method and get Bitmap from this Drawable to pass it to Canvas object I get java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor. Here is the code:
Drawable homeImage = mHomeImage.getBackground(); // my ImageView
homeImage.mutate();
Canvas c = new Canvas(((BitmapDrawable)homeImage).getBitmap());
Is there any way to modify this Bitmap without creating it's copy?
Try this
Bitmap bmp1 = (((BitmapDrawable)homeImage).getBitmap())
.copy(Config.ARGB_8888, true);
Canvas c = new Canvas(bmp1);
You will need to create a new bitmap for the canvas. As the canvas uses the bitmap we pass to store whats drawn, the bitmap should be mutable.
I want to merge two images and then save them on the Android SDCard.One is from the camera and one from the resources folder. The problem is that i get this error: Caused by: java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor. Thanks.
Bitmap bottomImage = BitmapFactory.decodeResource(getResources(),R.drawable.blink);
Bitmap topImage = (Bitmap) data.getExtras().get("data");
// As described by Steve Pomeroy in a previous comment,
// use the canvas to combine them.
// Start with the first in the constructor..
Canvas comboImage = new Canvas(bottomImage);
// Then draw the second on top of that
comboImage.drawBitmap(topImage, 0f, 0f, null);
// bottomImage is now a composite of the two.
// To write the file out to the SDCard:
OutputStream os = null;
try {
os = new FileOutputStream("/sdcard/DCIM/Camera/" + "myNewFileName.png");
bottomImage.compress(CompressFormat.PNG, 50, os);
//Bitmap image.compress(CompressFormat.PNG, 50, os);
} catch(IOException e) {
Log.v("error saving","error saving");
e.printStackTrace();
}
Managed to fix it by simply doing this change:
int w = bottomImage.getWidth();
int h = bottomImage.getHeight();
Bitmap new_image = Bitmap.createBitmap(w, h ,bottomImage.getConfig());
The problem now is that it doesn't saves the image. Do you know why?
This will help you =)
Edit: (embed answer from link)
the only static "constructor" for Bitmap returning a mutable one is:
(Class: Bitmap) public static Bitmap createBitmap(int width, int
height, boolean hasAlpha)
Returns: a mutable bitmap with the specified width and height.
So you could work with getPixels/setPixels or like this:
Bitmap bitmapResult = bm.createBitmap(widthOfOld, heightOfOld, hasAlpha);
Canvas c = new Canvas();
c.setDevice(bitmapResult); // drawXY will result on that Bitmap
c.drawBitmap(bitmapOld, left, top, paint);
how to get the drawable from Bitmap: by using the BitmapDrawable-Subclass which extends Drawable, like this:
Bitmap myBitmap = BitmapFactory.decode(path);
Drawable bd = new BitmapDrawable(myBitmap);
The bitmap you are retrieving is immutable, meaning it can't be modified. Although it doesn't specify on the Canvas page that the constructor needs a mutable bitmap, it does.
To create a mutable bitmap, you can use this method.
i am trying to edit images. but i am getting errors with setPixels.
picw = pic.getWidth();
pich = pic.getHeight();
picsize = picw*pich;
int[] pix = new int [picsize];
pic.getPixels(pix, 0, picw, 0, 0, picw, pich);
pic.setPixels(pix,0,pic.getWidth(),0,0,pic.getWidth(),pic.getHeight());
but i am getting illegal state exception with setPixels
Caused by: java.lang.IllegalStateException
at android.graphics.Bitmap.setPixels(Bitmap.java:878)
at com.sandyapps.testapp.testapp.onCreate(testapp.java:66)
I think your Bitmap is not mutable (see setPixel()'s documentation).
If so, create a mutable copy of this Bitmap (using Bitmap.copy(Bitmap.Config config, boolean isMutable) as an example) and work on this one.
It's simple, just use the following command to change it to a mutable Bitmap:
myBitmap = myBitmap.copy( Bitmap.Config.ARGB_8888 , true);
Now the Bitmap myBitmap is replaced by the same Bitmap but this time is mutable
You can also choose another way of storing Pixels (ARGB_8888 etc..):
https://developer.android.com/reference/android/graphics/Bitmap.Config.html
Most probably your pic is immutable. By default, any bitmap created from drawable would be immutable.
If you need to modify an existing bitmap, you should do following:
// Create a bitmap of the same size
Bitmap newBmp = Bitmap.createBitmap(pic.getWidth(), pic.getHeight(), Config.ARGB);
// Create a canvas for new bitmap
Canvas c = new Canvas(newBmp);
// Draw your old bitmap on it.
c.drawBitmap(pic, 0, 0, new Paint());
I had the same problem. Use to fix it:
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inMutable = true;
Bitmap bitmap = BitmapFactory.decodeResource( getResources(), R.drawable.my_bitmap, opt );
I was facing this problem and finally fixed after long time.
public static void filterApply(Filter filter){
Bitmap bitmcopy = PhotoModel.getInstance().getPhotoCopyBitmap();
//custom scalling is important to apply filter otherwise it will not apply on image
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bitmcopy, bitmcopy.getWidth()-1, bitmcopy.getHeight()-1, false);
filter.processFilter(scaledBitmap);
filterImage.setImageBitmap(scaledBitmap);
}
I am facing a problem while decoding an image:
Bitmap bMap = BitmapFactory.decodeResource(getResources(), R.drawable.smile);
mCanvas = new Canvas(bMap);
as BitmapFactory.decodeResource() returns an immutable object, which we cannot pass to the constructor of Canvas class.
Can I use the function
BitmapFactory.decodeResource(getResources(),Resource, option opt)
as BitmapFactory.options() is used for making the bitmap factory to return only mutable objects, no matter if the image is from "src" or dynamic.
Please help me out to create an image into canvas.