Saving View bitmap with getDrawingCache gives a black image - android

Everything I tried with setDrawingCacheEnabled and getDrawingCache was not working. The system was making an image but it just looked black.
Other people on SO seemed to be having a similar problem but the answers seemed either too complicated or irrelevant to my situation. Here are some of the ones I looked at:
Save view like bitmap, I only get black screen
Screenshot shows black
getDrawingCache always returns the same Bitmap
Convert view to bitmap on Android
bitmap is not saving properly only black image
Custom view converting to bitmap returning black image
And here is my code:
view.setDrawingCacheEnabled(true);
Bitmap bitmap = view.getDrawingCache();
try {
FileOutputStream stream = new FileOutputStream(getApplicationContext().getCacheDir() + "/image.jpg");
bitmap.compress(CompressFormat.JPEG, 80, stream);
stream.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
view.setDrawingCacheEnabled(false);
I'm sharing my answer below in case anyone else makes the same mistake I did.

My problem was that my view was a TextView. The text on the TextView was black (naturally) and in the app the background looked white. However, I later recalled reading that a view's background is by default transparent so that whatever color is below shows through.
So I added android:background="#color/white" to the layout xml for the view and it worked. When I had been viewing the image before I had been looking at black text over a black background.
See the answer by #BraisGabin for an alternate way that does not require overdrawing the UI.

I just found a good option:
final boolean cachePreviousState = view.isDrawingCacheEnabled();
final int backgroundPreviousColor = view.getDrawingCacheBackgroundColor();
view.setDrawingCacheEnabled(true);
view.setDrawingCacheBackgroundColor(0xfffafafa);
final Bitmap bitmap = view.getDrawingCache();
view.setDrawingCacheBackgroundColor(backgroundPreviousColor);
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream);
view.setDrawingCacheEnabled(cachePreviousState);
Where 0xfffafafa is the desired background color.

Used below code to get bitmap image for view it work fine.
public Bitmap loadBitmapFromView(View v) {
DisplayMetrics dm = getResources().getDisplayMetrics();
v.measure(View.MeasureSpec.makeMeasureSpec(dm.widthPixels,
View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(dm.heightPixels,
View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap returnedBitmap =
Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}

Related

Save view as an image in android

I am working on a project in which I have created a custom view with transparent background. Now I want to create an image of this view. I am using the below code to save and create an image from bitmap, but the generated image has black background and not transparent. I want transparent background. How can I achieve this?
view = suraVersesFragment.getMyView();
view.setBackgroundColor(Color.TRANSPARENT);
Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
c.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
view.draw(c);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "temporary_file.png");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
For receiving a non scaled bitmap of a view you can call this method after you enabled the drawing cache
view.getDrawingCache()
the api tells this about the method:
Returns the bitmap in which this view drawing is cached. The returned bitmap is null when caching is disabled. If caching is enabled and the cache is not ready, this method will create it. Calling draw(android.graphics.Canvas) will not draw from the cache when the cache is enabled. To benefit from the cache, you must request the drawing cache by calling this method and draw it on screen if the returned bitmap is not null.
Note about auto scaling in compatibility mode: When auto scaling is not enabled, this method will create a bitmap of the same size as this view. Because this bitmap will be drawn scaled by the parent ViewGroup, the result on screen might show scaling artifacts. To avoid such artifacts, you should call this method by setting the auto scaling to true. Doing so, however, will generate a bitmap of a different size than the view. This implies that your application must be able to handle this size.
you also can set the background's color
view.setDrawingCacheBackgroundColor(Color.XY)
you can look this also up here:
http://developer.android.com/reference/android/view/View.html#getDrawingCache(boolean)
http://developer.android.com/reference/android/view/View.html#getDrawingCache()
http://developer.android.com/reference/android/view/View.html#setDrawingCacheBackgroundColor(int)
Hey Hi Try this for transparent
Bitmap bitmap= Bitmap.createBitmap(255, 255, Bitmap.Config.ARGB_8888);
after that try this line (A is alpha value interval is 0-255 and 0 is fully transparent).
bitmap.eraseColor(Color.argb(AAA,RRR,GGG,BBB));
Check This

android achartengine : font appearing as double when exported as bitmap from graph

Am drawing a graph using AChartEngine where I'm having text (i.e. annotations, as they call in AChartEngine). They appear fine when seen on the screen, as you can see below :
but when the screen is saved as bitmap, the text appears with only the outline of each letter displayed as you can see below :
and this is how I get the bitmap from the view (ie. I am taking a screenshot of the graph)
Bitmap bitmap;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
options.inInputShareable = true;
Bitmap dummy = null;
try {
dummy = BitmapFactory.decodeStream(context.getAssets().open("icon_add.png"), new Rect(-1,-1,-1,-1), options);
} catch (IOException e) {
e.printStackTrace();
}
bitmap = Bitmap.createBitmap(deviceWidth,
deviceHeight, Bitmap.Config.ARGB_8888); // use ARGB_4444 if outofmemory
Canvas c = new Canvas(bitmap);
c.drawColor(Color.WHITE);
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight() + 15);
view.draw(c);
can someone please help?
This code works for me:
Bitmap cache;
view.buildDrawingCache();
cache = Bitmap.createBitmap(view.getDrawingCache());
view.destroyDrawingCache();

Convert view to bitmap

I have a view I want to create a bitmap for that view(later I want to print that bitmap). What I have tried is as follows
private Bitmap convertViewToBitMap() {
View v = rootView; //rootView is my view to be converted in bitmap
v.setDrawingCacheEnabled(true);
Bitmap b = v.getDrawingCache();
return b;
}
My view "rootview" is a expandable list, when I call convertViewToBitMap(), I get the bitmap of view which is visible on screen, but if view is expanded, the expanded part which is going out of screen does not come in bitmap. So is there a way to get a bitmap of complete view even if it is partially visible on screen?
Try this:
Make some adjustments to your view. "Measure" method defines the proper dimensions of your view (change 1000 and 600 to what suits you best)
view.measure(MeasureSpec.makeMeasureSpec(1000, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(600, MeasureSpec.EXACTLY));
Re-define your view with the new measurements (change also 0,0)
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Create the bitmap
Bitmap bm=Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
After that, you can draw your bitmap to any view
Canvas cn=new Canvas(bm);
anyview.draw(cn);
Also, you can save the bitmap into a file
try {
FileOutputStream out = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}

Android combine pictures

Hy, I tried to search this but not very much luck
the most similar is this one
http://ketankantilal.blogspot.com/2011/03/how-to-combine-images-and-store-to.html
Anyhow, I'm developing for android.
The question is I have images in png format (or jpg as bmp is quite large for my app).
How can I combine three images from top to bottom.
I do not need to save them on sd just to display them.
Thanks, and sorry if a similar question with answer exists.
You could use a Canvas and then draw each Bitmap (assuming each image is loaded into a Bitmap object) using appropriate top and left offsets.
You would increase the top offset of the next bitmap by the total size of the previously drawn Bitmaps.
Check out http://developer.android.com/reference/android/graphics/Canvas.html
example:
public void stackImages(Context ctx)
{
// base image, if new images have transparency or don't fill all pixels
// whatever is drawn here will show.
Bitmap result = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);
// b1 will be on top
Bitmap b1 = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
// b2 will be below b1
Bitmap b2 = Bitmap.createBitmap(400, 200, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(result);
c.drawBitmap(b1, 0f, 0f, null);
// notice the top offset
c.drawBitmap(b2, 0f, 200f, null);
// result can now be used in any ImageView
ImageView iv = new ImageView(ctx);
iv.setImageBitmap(result);
// or save to file as png
// note: this may not be the best way to accomplish the save
try {
FileOutputStream out = new FileOutputStream(new File("some/file/name.png"));
result.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}

Print Bitmaps onto other bitmap android

I am trying to make my game a bit easier on the phone, so I am trying to figure out a way to print a bunch of bitmaps onto another big one, so I can just do it once, rather than every time the screen is redrawn. So, is there any way to do this? I know there is a way to print everything that is printed to the canvas to a bitmap, but I can't seem to get that to work. If that is the only way can someone explain how to do that? Thanks in advance.
Here is something I tried, but it didn't work out so well
Bitmap background;
Canvas canvas;
private void methodName() {
background = Bitmap.createBitmap(width, height, someKindOfConfigThing);
canvas = new Canvas(background);
canvas.drawBitmap(blahblah);
}
What you would do is to create the main bitmap, attach that to a canvas to which you can draw.
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.RGB_565);
Canvas c = new Canvas(bitmap);
You can draw (parts of) bitmaps to this canvas using
c.drawBitmap(anotherBitmap, transformMatrix, paint);
To attach the main bitmap to the view you would create a new ImageView, call setImageBitmap passing your main bitmap and set it as the current contentview using setContentView.
If you want to combine multiple bitmaps to another big one and reuse that, you already on the right way! Show us what you have done and tell us what the result is. I guess we can help you :)
[update] it should be possible to save this new bitmap to disc or store it temporarily as a variable:
private void methodName() {
background = Bitmap.createBitmap(width, height, someKindOfConfigThing);
canvas = new Canvas(background);
// drawing on the canvas should change the bitmap "background" too
canvas.drawBitmap(blahblah);
FileOutputStream fos = null;
try {
fos = new FileOutputStream("/path/to/image.png");
background.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.close();
} catch (Exception e) {
// catching...
}
}

Categories

Resources