I want to take a picture of a view in Activity and share this picture.
First I use this method :
private Bitmap getShareViewShot() {
this.setDrawingCacheEnabled(true);
this.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(this.getDrawingCache(), 0, mSharePageRoot.getTop(), this.getWidth(), mSharePageRoot.getBottom());
this.setDrawingCacheEnabled(false);
return bitmap;
}
But if the view is in a ScrollView and the view has scrolled outside the screen, this method can't get a whole picture of this view.
So I change this method to below :
private Bitmap getShareViewShot() {
Bitmap bitmap = Bitmap.createBitmap(mSharePageRoot.getWidth(), mSharePageRoot.getHeight(),
Bitmap.Config.ARGB_8888);
mSharePageRoot.layout(0, 0, mSharePageRoot.getLayoutParams().width, mSharePageRoot.getLayoutParams().height);
final Canvas canvas = new Canvas(bitmap);
mSharePageRoot.draw(canvas);
return bitmap;
}
But another question comes: this view has no backgroud, so the picture I get has a black backgroud.In my code ,the Activity have a network image as the backgroud, so this means this method can't get the backgroud of the activity.
Please forgive me for my bad English.
Is there any other method ? thanks.
Yes, there is another method. There is a library by google called ASL(Android screenshot library). It's pretty simple.
https://code.google.com/archive/p/android-screenshot-library/wikis/DeveloperGuide.wiki
You can draw background by canvas, like this:
private Bitmap getShareViewShot() {
Bitmap bitmap = Bitmap.createBitmap(mSharePageRoot.getWidth(), mSharePageRoot.getHeight(),
Bitmap.Config.ARGB_8888);
mSharePageRoot.layout(0, 0, mSharePageRoot.getLayoutParams().width, mSharePageRoot.getLayoutParams().height);
final Canvas canvas = new Canvas(bitmap);
// the bitmap will have a white background
canvas.drawColor(0xffffffff);
mSharePageRoot.draw(canvas);
return bitmap;
}
Related
I would like to ask help. I want to take screenshot. This is working, but ImageView rounded corners are not rounded on the taken screenshots (and elevation shadows missing too). I used
imageView.setClipToOutline(true);
to make this work on the phone, but on the screenshots they are rectangular.
These are my screenshot utils:
public class ScreenShotUtils {
public static Bitmap screenShotFromCanvas(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
public static Bitmap screenShotFromDrawingCache(View view) {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.destroyDrawingCache();
view.setDrawingCacheEnabled(false);
return bitmap;
}
Both method has the same result.
However i noticed, that if i turn the hardware acceleration off, the layout looks like the same as on the screenshots.
This is how it looks like after take screenshot:
This is how it should be:
Finally i solved my problem with MediaProjectionManager.
I am working on application that allows users to shade a portion of bitmap when the swipe on it. Then when he finishes swiping I call a method to crop that portion of bitmap and perform some function(but cropped bitmap is not saved anywhere so doubt there is any problem here). On click on imageView I reset the bitmap with original bitmap. There is also a functionality to rotate the bitmap.I have two bitmap objects bill(user actually swipes on it) and billOrg(original bitmap as it is). Below are the methods.
private void drawShade(float left,float top,float right,float bottom){
//this method draws shade on bitmap. Coordinates are sent from onTouchEvent
TAG = "drawShade";
//parseTouchPointsString();
Bitmap tempBitmap = Bitmap.createBitmap(bill.getWidth(), bill.getHeight(), Bitmap.Config.RGB_565);
Log.d(TAG,"bill:"+bill.isMutable()+"tempBit:"+tempBitmap.isMutable()+"");
Canvas tempCanvas = new Canvas(tempBitmap);
tempCanvas.drawBitmap(bill,0,0,null);
tempCanvas.drawRoundRect(new RectF(left,top,right,bottom), 10, 10, shadePaint);
imgView.setImageDrawable(new BitmapDrawable(getResources(), tempBitmap));
if(fingerUp) {
Log.e("fingerUp",fingerUp+"");
bill = tempBitmap;
}
Log.d(TAG,"shade drawn at:"+left+","+top+","+right+","+bottom);
}
Here is method to rotate bitmap :
public void rotateImage(View v){
TAG = "rotateImage";
Matrix matrix = new Matrix();
matrix.postRotate(90);
Bitmap rotatedBitmap = Bitmap.createBitmap(bill , 0, 0, bill.getWidth(), bill.getHeight(), matrix, true);
bill = rotatedBitmap.copy(rotatedBitmap.getConfig(),true);
createScaledBitmap();
billOrg = bill.copy(rotatedBitmap.getConfig(),true);//bill.copy(bill.getConfig(),false);
setImage(bill);
rl.invalidate();
}
Method to reset bitmap on click :
private void resetImageView(boolean saveShade){
//the boolean var here tell whether to keep the shaded portion after reset or not
if(!saveShade) { //app crashes in this if block although I have try-catch.
try {
Canvas canvas = new Canvas(bill);
Log.e("resetImageView", "billOrg:" + billOrg.isMutable() + ",bill:" + bill.isMutable()); //returns true for both bitmap objects
canvas.drawBitmap(billOrg, 0, 0, null);
touchBounds = "";
tv_res.setText("");
rl.invalidate();
setImage(bill);
}catch(Exception ex){
Log.e("resetImage",ex.getMessage());
}
}else{
Canvas canvas = new Canvas(bill);
canvas.drawBitmap(bill, 0, 0, null);
touchBounds = "";
tv_res.setText("");
rl.invalidate();
setImage(bill);
}
}
All is fine except when user first swipes the image --> then rotates the image --> then clicks on bitmap.
All I get is this error: jni_helper.cc:110 Bitmap is of the wrong format: 4. No other exceptions.
As per my knowledge bitmaps usually throw errors if we try to modify a bitmap object which is immutable but I have made it mutable in all places. It prints mutable in logs too. I guess I am doing something wrong while modifying the bitmaps. I know might be confusing for you. I don't know how well I have explained. If you need any clarity kindly ask. I need some help.
Ok so I found out what was causing the problem.
Bitmap tempBitmap = Bitmap.createBitmap(bill.getWidth(), bill.getHeight(), Bitmap.Config.RGB_565);
In the drawShade() method was culprit. I changed the "Bitmap.Config.RGB_565" to bill.getConfig() and it was fixed.
I have a Picture object, loaded from an SVG file, and I have set hardwareAccelerated=false to make it works on all devices.
Since there is a bug on android 4.0.4, I have to convert the Picture to Bitmap and I do that, in this way:
...
...
public void draw(Canvas canvas) {
...
...
//myPicture size is 9000x5000 but I want to display only this portion
clipRect.set(50, 50, 370, 530);
Bitmap bmp = getBitmapFromPicture(myPicture, clipRect);
canvas.drawBitmap(bmp, 0, 0, null);
bmp.recycle();
...
...
}
public static Bitmap getBitmapFromPicture(Picture picture, RectF clipRect) {
Bitmap bitmap = Bitmap.createBitmap(Math.round(clipRect.width()), Math.round(clipRect.height()), Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
canvas.drawPicture(picture);
}
Now I want to clip the Picture because I want to display only the visible screen part of it.
But the canvas.drawPicture does not accept srcRect parameter.
How is it possible to achieve this?
EDIT:
By translate the canvas: canvas.translate(-50, -50) it seems that translate the bitmap, too.
You need to set a transform on the Canvas.
To move the portion of the picture at 50,50 down so it is on the bitmap (ie. at 0,0), just do:
canvas.translate(-50, -50);
So your method becomes:
public static Bitmap getBitmapFromPicture(Picture picture, RectF clipRect)
{
Bitmap bitmap = Bitmap.createBitmap(Math.round(clipRect.width()),
Math.round(clipRect.height()),
Config.RGB_565);
Canvas canvas = new Canvas(bitmap);
canvas.translate(-clipRect.left, -clipRect.top);
canvas.drawPicture(picture);
}
I'd like to use several CustomViews in my appwidget and thus want to create a bitmap out of every CustomView.
So i tried that with
Bitmap customBitmap = customView.getDrawingCache(true);
remoteViews.setImageViewBitmap(R.id.imageView1, customBitmap );
but it doesn't work at all.
Are there any suggestions?
yes, it is drawn on a canvas
I would do something like this:
public Bitmap createCustomView(){
Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// draw on the canvas:
// ...
return bitmap;
}
and then set the Bitmap to the ImageView:
remoteViews.setImageViewBitmap(R.id.imageView1, createCustomView() );
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...
}
}