Take a screenshot of a whole View [duplicate] - android

This question already has answers here:
Convert view to bitmap on Android
(9 answers)
Closed 1 year ago.
I have built a table which is basically done by HorizontalScrollView inside a ScrollView. I made the user can edit the fields.
Now I want to save the table on a screen, jpg, png, pdf or anything else.
The problem is - the table is nearly always bigger than the screen.
Is there a way to make a screenshot of the whole ScrollView layout? If not what do you think can do the job?

Actually I found the answer:
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}

ScrollView iv = (ScrollView) findViewById(R.id.scrollView);
Bitmap bitmap = Bitmap.createBitmap(
iv.getChildAt(0).getWidth(),
iv.getChildAt(0).getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
iv.getChildAt(0).draw(c);
// Do whatever you want with your bitmap
saveBitmap(bitmap);

Using #softwaresupply answer causes problem in my case where my view was getting redrawn and getting completely white. There is an easier solution to get screenshot where you don't even have to supply width and height as parameters.
Use Drawing Cache.
public static Bitmap loadBitmapFromView(View v) {
Bitmap bitmap;
v.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return bitmap;
}

It is impossible to make a screenshot of not-yet-rendered content (like off-screen parts of the ScrollView). However, you can make a multiple screenshots, scrolling content between each shot, then join images. Here is a tool which can automate this for you: https://github.com/PGSSoft/scrollscreenshot
Disclaimer: I'm author of this tool, it was published by my employer. Feature requests are welcome.

Download source code from here (Take screenshot of scrollview in android programmatically)
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#efefef"
android:orientation="vertical">
<Button
android:id="#+id/btn_screenshot"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="10dp"
android:text="Take ScreenShot"/>
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:background="#ffffff">
<LinearLayout
android:id="#+id/ll_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image2"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image3"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image5"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image6"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
MainActivity.xml
package deepshikha.com.screenshot;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
Button btn_screenshot;
ScrollView scrollView;
LinearLayout ll_linear;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
fn_permission();
}
private void init() {
btn_screenshot = findViewById(R.id.btn_screenshot);
scrollView = findViewById(R.id.scrollView);
ll_linear = findViewById(R.id.ll_linear);
btn_screenshot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), Screenshot.class);
startActivity(intent);
} else {
if (boolean_permission) {
Bitmap bitmap1 = loadBitmapFromView(ll_linear, ll_linear.getWidth(), ll_linear.getHeight());
saveBitmap(bitmap1);
} else {
}
}
}
});
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File("/sdcard/screenshotdemo.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Toast.makeText(getApplicationContext(), imagePath.getAbsolutePath() + "", Toast.LENGTH_SHORT).show();
boolean_save = true;
btn_screenshot.setText("Check image");
Log.e("ImageSave", "Saveimage");
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) ||
(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE))) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
Thanks!

You can pass the view a fresh instance of a Canvas built upon a Bitmap object.
Try with
Bitmap b = Bitmap.createBitmap(targetView.getWidth(),
targetView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
targetView.draw(c);
BitmapDrawable d = new BitmapDrawable(getResources(), b);
canvasView.setBackgroundDrawable(d);`
It actually did the job for me.

this work for me, hope it helpful for you too.
public static Bitmap getBitmapByView(ScrollView scrollView) {
int h = 0;
Bitmap bitmap = null;
//get the actual height of scrollview
for (int i = 0; i < scrollView.getChildCount(); i++) {
h += scrollView.getChildAt(i).getHeight();
scrollView.getChildAt(i).setBackgroundResource(R.color.white);
}
// create bitmap with target size
bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
scrollView.draw(canvas);
FileOutputStream out = null;
try {
out = new FileOutputStream("/sdcard/screen_test.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (null != out) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
} catch (IOException e) {
// TODO: handle exception
}
return bitmap;
}

I've tested a lot of codes and every time hitting NullPointerExeption. I discovered that when our view does not have a parent view, the provided width and height (Xml or Java) get ignored and get setted to MATCH_PARENT.
Finally I came up with this solution:
/**
* Take screen shot of the View
*
* #param v the view
* #param width_dp
* #param height_dp
*
* #return screenshot of the view as bitmap
*/
public static Bitmap takeScreenShotOfView(View v, int width_dp, int height_dp) {
v.setDrawingCacheEnabled(true);
// this is the important code :)
v.measure(View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), width_dp), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), height_dp), View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
// creates immutable clone
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
public static int dpToPx(Context context, int dp) {
Resources r = context.getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}

You might be able to use the drawing cache of a view, but I am not sure if this will hold the entire view or just what is rendered to the screen.
I would advise you hunt around on StackOverflow for similar questions, it has more than likely been asked before.

try this its works fine for me
TableLayout tabLayout = (TableLayout) findViewById(R.id.allview);
if (tabLayout != null) {
Bitmap image = Bitmap.createBitmap(tabLayout.getWidth(),
tabLayout.getHeight(), Config.ARGB_8888);
Canvas b = new Canvas(image);
tabLayout.draw(b);
}

//set button click listener
share = (Button)findViewById(R.id.share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
});
//then you have to create two method
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
After add this code into your app, run the app and check your local storage, you have created screen shot of whole page.

public static Bitmap loadBitmapFromView(ScrollView v) {
Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getChildAt(0).getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}

Taking a screenshot of a view, pass the view in the parameter
public static Bitmap getViewBitmap(View v) {
v.clearFocus();
v.setPressed(false);
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}

fun View.getScreenShot():Bitmap{
return Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888).apply {
draw(Canvas(this))
}
}

As mentioned here, you can use View::drawToBitmap function:
val bitmap = myView.drawToBitmap(/*Optional:*/ Bitmap.Config.ARGB_8888)
Just make sure to use the -ktx version of AndroidX Core library:
implementation("androidx.core:core-ktx:1.6.0")
Note: The -ktx version of libraries are the same as the non-ktx ones except they contain useful Kotlin extension functions.

Related

Take whole "Screenshot" of a scrollable View

In my Fragment's layout i have a ScrollView with a LinearLayout inside
<ScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- Other views -->
</LinearLayout>
</ScrollView>
So i need to create and share a picture of entire content of scrollview. All solutions i've tried take screenshot only of the visible area, and not of entire scrollview content. How can i do?
I hope this is work for you.. source here. this is not technically a screenshot code. but this code convert the whole layout view into bitmap
Bitmap bitmap = getBitmapFromView(scrollview, scrollview.getChildAt(0).getHeight(), scrollview.getChildAt(0).getWidth());
//create bitmap from the ScrollView
private Bitmap getBitmapFromView(View view, int height, int width) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return bitmap;
}
call below method getYourLayout() where you want to take snap of your layout. In this i attach layout in one dialog & take snapshop of root layout whithout showing dialog to user. All thing happens in background.
private void getYourLayout() {
try {
Dialog fb_event_info = new Dialog(YourActivity.this);
fb_event_info.requestWindowFeature(Window.FEATURE_NO_TITLE);
fb_event_info.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
fb_event_info.setContentView(R.layout.yourXmlLayoutFile);
final LinearLayout lnr_fb_info = (LinearLayout) fb_event_info.findViewById(R.id.container);
TextView tv_fb_event_name = (TextView) fb_event_info.findViewById(R.id.tv_fb_event_name);
tv_fb_event_name.setTypeface(Global.setCubanoFont(EventDetailActivity.this));
tv_fb_event_name.setText(tv_event_name.getText().toString());
lnr_fb_info.setDrawingCacheEnabled(true);
lnr_fb_info.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
lnr_fb_info.layout(0, 0, lnr_fb_info.getMeasuredWidth(), lnr_fb_info.getMeasuredHeight());
lnr_fb_info.buildDrawingCache(true);
bitmap = Bitmap.createBitmap(lnr_fb_info.getDrawingCache());
saveImage(bitmap);
} catch (Exception e) {
}
}
This Function is for Saving your Bitmap as file.
private void saveImage(Bitmap bitmap) {
try {
Log.e("----------in---", "saveImage....: ");
if (!rootFile.exists())
rootFile.mkdirs();
long time = System.currentTimeMillis();
fname = "mynight-" + time + ".png";
rootFile = new File(rootFile, fname);
Log.e("----------in---", "saveImage...1.: ");
try {
FileOutputStream Fout = new FileOutputStream(rootFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, Fout);
sendShareFb();
Fout.flush();
Fout.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Below function is for share your image on facebook.
private void sendShareFb() {
try {
Log.e("----------in---", "sendShareFb....: ");
Intent fbIntent = new Intent(Intent.ACTION_SEND);
File imageFile = new File(rootFile.toString());
fbIntent.putExtra(Intent.EXTRA_TEXT, "Share..");
fbIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
fbIntent.setType("image/jpeg/png");
PackageManager pm = getPackageManager();
List<ResolveInfo> lract = pm.queryIntentActivities(fbIntent, PackageManager.MATCH_DEFAULT_ONLY);
boolean resolved = false;
for (ResolveInfo ri : lract) {
if (ri.activityInfo.name.toLowerCase().contains("facebook")) {
fbIntent.setClassName(ri.activityInfo.packageName, ri.activityInfo.name);
resolved = true;
break;
}
}
if (!resolved) {
Toast.makeText(EventDetailActivity.this, "Vous ne semblez pas avoir Facebook installé sur cet appareil", Toast.LENGTH_SHORT).show();
}
startActivity(resolved ? fbIntent : Intent.createChooser(fbIntent, "Choose one"));
} catch (final ActivityNotFoundException e) {
e.printStackTrace();
}
}
Sure that this will Help you. Because this solution has fixed my problem many time.

saving frame layout as bitmap with its subViews but imageView(subView) giving blackscreen

I have a framelayout.
it includes a button.
At runtime I click the button to pick an image from the gallery.
I create a imageView ,set the chosen image from the gallery on the imageView and add the imageView to framelayout.
then i save the entire view(framelayout) as a bitmap.
But the saved bitmap only shows the button and a black screen where the imageView should be.
I tried a lot of ways but could not resolve it...
pls help
public class MainActivity extends AppCompatActivity {
Button b;
RelativeLayout frame;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
b = (Button) findViewById(R.id.b);
frame = (RelativeLayout) findViewById(R.id.frame);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, 1);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode){
case 1 :
Uri selectedImage = data.getData();
try {
bitmap = MediaStore.Images.Media.getBitmap(
MainActivity.this.getContentResolver(), selectedImage);
} catch (IOException e) {
e.printStackTrace();
}
ImageView i = new ImageView(MainActivity.this);
i.setImageBitmap(bitmap);
frame.addView(i);
frame.invalidate();
Bitmap bitmapFromView = Bitmap.createBitmap(frame.getWidth(),frame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvass = new Canvas(bitmapFromView);
frame.draw(canvass);
saveBitmap(bitmapFromView);
break;
}
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
MediaScannerConnection.scanFile(getApplicationContext(),
new String[]{imagePath.getAbsolutePath()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
// TODO Auto-generated method stub
}
});
}
/*
also tried this...not working
public static Bitmap loadBitmapFromView(View v) {
Bitmap bitmap;
v.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return bitmap;
}
*/
}
Now finally i made a code working in most of the device i had tested
1) MainActivity.class
public class MainActivity extends AppCompatActivity {
private final int SELECT_PHOTO = 2;
private ImageView contactimage;
private LinearLayout content;
private TextView textall;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
content = (LinearLayout) findViewById(R.id.frame_save);
contactimage = (ImageView) findViewById(R.id.contactimage);
textall = (TextView) findViewById(R.id.textall);
textall.setText("MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst MY TEst\n" +
" MY TEst MY TEst MY TEst MY TEst MY TEst");
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, SELECT_PHOTO);
}
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case SELECT_PHOTO:
if (resultCode == RESULT_OK) {
try {
final Uri imageUri = data.getData();
final InputStream imageStream = getContentResolver().openInputStream(imageUri);
final Bitmap selectedImage = BitmapFactory.decodeStream(imageStream);
contactimage.setImageBitmap(selectedImage);
try {
content.setDrawingCacheEnabled(true);
content.setDrawingCacheEnabled(true);
content.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
content.layout(0, 0, content.getMeasuredWidth(), content.getMeasuredHeight());
content.buildDrawingCache(true);
Bitmap bitmap = getBitmapFromView(content);
content.setDrawingCacheEnabled(false);
File file, f = null;
if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
file = new File(android.os.Environment.getExternalStorageDirectory(), "Handcare");
if (!file.exists()) {
file.mkdirs();
}
f = new File(file.getAbsolutePath() + File.separator + "MyImage.png");
}
FileOutputStream ostream = new FileOutputStream(f);
bitmap.compress(Bitmap.CompressFormat.PNG, 10, ostream);
ostream.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
}
private Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return returnedBitmap;
}
}
2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="#android:color/white">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:id="#+id/frame_save">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textColor="#android:color/black"
android:id="#+id/textall"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/contactimage"
android:layout_margin="10dp"/>
</LinearLayout>
</LinearLayout>
3) In manifest
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
I did it.
I WAS ADDING THE IMAGE AND SAVING IT SEQUENTIALLY IN onActivityResult();
this:
ImageView i = new ImageView(MainActivity.this);
i.setImageBitmap(bitmap);
frame.addView(i);
frame.invalidate();
and this:
Bitmap bitmapFromView = Bitmap.createBitmap(frame.getWidth(),frame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvass = new Canvas(bitmapFromView);
frame.draw(canvass);
saveBitmap(bitmapFromView);
It seems that although the added image was visible to me on device but internally android had not processed it.And before that that could happen I was trying to save the view.
Now I finally solved it by adding the the imageView in onActivityResult();
and saving this view on a separate button click.
I also got positive result when I fired a worker thread which would sleep for 1 second after adding the imageview.
Then in postExecute() of the worker thread I saved the view as bitmap.

how to take screen shots of full scroll view in android bigger than screen [duplicate]

This question already has answers here:
Convert view to bitmap on Android
(9 answers)
Closed 1 year ago.
I have built a table which is basically done by HorizontalScrollView inside a ScrollView. I made the user can edit the fields.
Now I want to save the table on a screen, jpg, png, pdf or anything else.
The problem is - the table is nearly always bigger than the screen.
Is there a way to make a screenshot of the whole ScrollView layout? If not what do you think can do the job?
Actually I found the answer:
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
ScrollView iv = (ScrollView) findViewById(R.id.scrollView);
Bitmap bitmap = Bitmap.createBitmap(
iv.getChildAt(0).getWidth(),
iv.getChildAt(0).getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
iv.getChildAt(0).draw(c);
// Do whatever you want with your bitmap
saveBitmap(bitmap);
Using #softwaresupply answer causes problem in my case where my view was getting redrawn and getting completely white. There is an easier solution to get screenshot where you don't even have to supply width and height as parameters.
Use Drawing Cache.
public static Bitmap loadBitmapFromView(View v) {
Bitmap bitmap;
v.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return bitmap;
}
It is impossible to make a screenshot of not-yet-rendered content (like off-screen parts of the ScrollView). However, you can make a multiple screenshots, scrolling content between each shot, then join images. Here is a tool which can automate this for you: https://github.com/PGSSoft/scrollscreenshot
Disclaimer: I'm author of this tool, it was published by my employer. Feature requests are welcome.
Download source code from here (Take screenshot of scrollview in android programmatically)
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#efefef"
android:orientation="vertical">
<Button
android:id="#+id/btn_screenshot"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="10dp"
android:text="Take ScreenShot"/>
<ScrollView
android:id="#+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:background="#ffffff">
<LinearLayout
android:id="#+id/ll_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image2"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image3"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image5"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="#drawable/image6"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
MainActivity.xml
package deepshikha.com.screenshot;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
Button btn_screenshot;
ScrollView scrollView;
LinearLayout ll_linear;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
fn_permission();
}
private void init() {
btn_screenshot = findViewById(R.id.btn_screenshot);
scrollView = findViewById(R.id.scrollView);
ll_linear = findViewById(R.id.ll_linear);
btn_screenshot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), Screenshot.class);
startActivity(intent);
} else {
if (boolean_permission) {
Bitmap bitmap1 = loadBitmapFromView(ll_linear, ll_linear.getWidth(), ll_linear.getHeight());
saveBitmap(bitmap1);
} else {
}
}
}
});
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File("/sdcard/screenshotdemo.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Toast.makeText(getApplicationContext(), imagePath.getAbsolutePath() + "", Toast.LENGTH_SHORT).show();
boolean_save = true;
btn_screenshot.setText("Check image");
Log.e("ImageSave", "Saveimage");
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) ||
(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE))) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
Thanks!
You can pass the view a fresh instance of a Canvas built upon a Bitmap object.
Try with
Bitmap b = Bitmap.createBitmap(targetView.getWidth(),
targetView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
targetView.draw(c);
BitmapDrawable d = new BitmapDrawable(getResources(), b);
canvasView.setBackgroundDrawable(d);`
It actually did the job for me.
this work for me, hope it helpful for you too.
public static Bitmap getBitmapByView(ScrollView scrollView) {
int h = 0;
Bitmap bitmap = null;
//get the actual height of scrollview
for (int i = 0; i < scrollView.getChildCount(); i++) {
h += scrollView.getChildAt(i).getHeight();
scrollView.getChildAt(i).setBackgroundResource(R.color.white);
}
// create bitmap with target size
bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
scrollView.draw(canvas);
FileOutputStream out = null;
try {
out = new FileOutputStream("/sdcard/screen_test.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (null != out) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
} catch (IOException e) {
// TODO: handle exception
}
return bitmap;
}
I've tested a lot of codes and every time hitting NullPointerExeption. I discovered that when our view does not have a parent view, the provided width and height (Xml or Java) get ignored and get setted to MATCH_PARENT.
Finally I came up with this solution:
/**
* Take screen shot of the View
*
* #param v the view
* #param width_dp
* #param height_dp
*
* #return screenshot of the view as bitmap
*/
public static Bitmap takeScreenShotOfView(View v, int width_dp, int height_dp) {
v.setDrawingCacheEnabled(true);
// this is the important code :)
v.measure(View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), width_dp), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), height_dp), View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
// creates immutable clone
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
public static int dpToPx(Context context, int dp) {
Resources r = context.getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
You might be able to use the drawing cache of a view, but I am not sure if this will hold the entire view or just what is rendered to the screen.
I would advise you hunt around on StackOverflow for similar questions, it has more than likely been asked before.
try this its works fine for me
TableLayout tabLayout = (TableLayout) findViewById(R.id.allview);
if (tabLayout != null) {
Bitmap image = Bitmap.createBitmap(tabLayout.getWidth(),
tabLayout.getHeight(), Config.ARGB_8888);
Canvas b = new Canvas(image);
tabLayout.draw(b);
}
//set button click listener
share = (Button)findViewById(R.id.share);
share.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
});
//then you have to create two method
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
After add this code into your app, run the app and check your local storage, you have created screen shot of whole page.
public static Bitmap loadBitmapFromView(ScrollView v) {
Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getChildAt(0).getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Taking a screenshot of a view, pass the view in the parameter
public static Bitmap getViewBitmap(View v) {
v.clearFocus();
v.setPressed(false);
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
fun View.getScreenShot():Bitmap{
return Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888).apply {
draw(Canvas(this))
}
}
As mentioned here, you can use View::drawToBitmap function:
val bitmap = myView.drawToBitmap(/*Optional:*/ Bitmap.Config.ARGB_8888)
Just make sure to use the -ktx version of AndroidX Core library:
implementation("androidx.core:core-ktx:1.6.0")
Note: The -ktx version of libraries are the same as the non-ktx ones except they contain useful Kotlin extension functions.

writing app to take a screenshot, and then save it to the gallery of my Android phone, but the saved screenshot is completely black

Here is my Screenshot class. The app is saving the screenshot in my gallery, which is what I want, but the image is completely black! If you had any suggestions to make this work, they would be much appreciated! Thanks!
public class Screenshot extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// set event listener for the Save Contact Button
Button button =
(Button) findViewById(R.id.button);
button.setOnClickListener(buttonClicked);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.screenshot, menu);
return true;
}
// responds to event generated when user clicks the Done Button
OnClickListener buttonClicked = new OnClickListener()
{
#Override
public void onClick(View v)
{
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
};
public void saveBitmap(Bitmap bitmap) {
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.LinearLayout01);
Bitmap b = Bitmap.createBitmap(mainLayout.getWidth(), mainLayout.getHeight(),
Bitmap.Config.ARGB_8888);
MediaStore.Images.Media.insertImage(getContentResolver(), b, "image.png" , "screenshot");
}
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
}
and here is my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/LinearLayout01"
>
<Button
android:id="#+id/button"
android:layout_height = "wrap_content"
android:layout_width ="wrap_content"
android:text = "take screenshot"
android:onClick = "DoIt"
/>
<ImageView
android:id="#+id/eiffelTowerImageView"
android:layout_width="200dip"
android:layout_height="200dip"
android:layout_toRightOf="#+id/colosseumImageView"
android:src="#drawable/eiffeltower" />
</LinearLayout>
This Code Works like a Charm for me
private static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
Log.e("Screenshot", "taken successfully");
return b;
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory()
+ "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(CompressFormat.JPEG, 100, fos);
Log.e("Screenshot", "saved successfully");
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
Get Activity in OnCreate()
Activity activity = (MainActivity) this;
Then Call these Function where ever you want
Bitmap bitmap = takeScreenShot(activity);
saveBitmap(bitmap);
Your solution will only work for taking a screenshot of your own app (since it uses the app's drawing cache), so if that's what you want to do, you'll have to make sure it's visible on the screen. Anything that your app doesn't have permission to view (like another app running behind it) will not show up or, as you're seeing, will show up black.
I suggest you look at this other screenshot question here to see the constraints under which you're working. Primarily, since you presumably don't have root permissions or a signature application (which would only be true if you compiled your own ROM), then you can't capture the framebuffer, which is what the native Android screenshot mechanism in 4.0+ can do for you if you press a specific key combination (on my Galaxy Nexus it's power+volume down).
Try this code :
public class MainActivity extends Activity {
Button btn_shoot;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn_shoot = (Button)findViewById(R.id.btn_shoot);
btn_shoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View view = findViewById(R.id.relativelayout);
view = view.getRootView();
view.setDrawingCacheEnabled(true);
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap bitmap = view.getDrawingCache();
BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setBackgroundDrawable(bitmapDrawable);
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
//we check if external storage is available, otherwise display an error message to the user
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/Tutorial_ScreenShot");
directory.mkdirs();
String filename = "screenshot" + i + ".jpg";
File yourFile = new File(directory, filename);
while (yourFile.exists()) {
i++;
filename = "screenshot" + i + ".jpg";
yourFile = new File(directory, filename);
}
if (!yourFile.exists()) {
if (directory.canWrite())
{
try {
FileOutputStream out = new FileOutputStream(yourFile, true);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
Toast.makeText(MainActivity.this, "File exported to /sdcard/Tutorial_ScreenShot/screenshot" + i + ".jpg", Toast.LENGTH_SHORT).show();
i++;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
else
{
Toast.makeText(MainActivity.this, "SD Card not available!", Toast.LENGTH_SHORT).show();
}
}
});
}
}

How to convert all content in a scrollview to a bitmap?

I use below code to convert, but it seems can only get the content in the display screen and can not get the content not in the display screen.
Is there a way to get all the content even out of scroll?
Bitmap viewBitmap = Bitmap.createBitmap(mScrollView.getWidth(),mScrollView.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(viewBitmap);
mScrollView.draw(canvas);
We can convert all the contents of a scrollView to a bitmap image using the code shown below
private void takeScreenShot()
{
View u = ((Activity) mContext).findViewById(R.id.scroll);
HorizontalScrollView z = (HorizontalScrollView) ((Activity) mContext).findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Bitmap b = getBitmapFromView(u,totalHeight,totalWidth);
//Save bitmap
String extr = Environment.getExternalStorageDirectory()+"/Folder/";
String fileName = "report.jpg";
File myPath = new File(extr, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(mContext.getContentResolver(), b, "Screen", "screen");
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth,totalHeight , Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
The Pops answer is really good, but in some case you could have to create a really big bitmap which could trigger a OutOfMemoryException when you create the bitmap.
So I made a little optimization to be gently with the memory :)
public static Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
int height = Math.min(MAX_HEIGHT, totalHeight);
float percent = height / (float)totalHeight;
Bitmap canvasBitmap = Bitmap.createBitmap((int)(totalWidth*percent),(int)(totalHeight*percent), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(canvasBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
canvas.save();
canvas.scale(percent, percent);
view.draw(canvas);
canvas.restore();
return canvasBitmap;
}
This one works for me
To save the bitmap check runtime permission first
#OnClick(R.id.donload_arrow)
public void DownloadBitMap()
{
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
{
downloadData();
Log.e("callPhone: ", "permission" );
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
Toast.makeText(this, "need permission", Toast.LENGTH_SHORT).show();
}
}
To get bitmap
private void downloadData() {
ScrollView iv = (ScrollView) findViewById(R.id.scrollView);
Bitmap bitmap = Bitmap.createBitmap(
iv.getChildAt(0).getWidth()*2,
iv.getChildAt(0).getHeight()*2,
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
c.scale(2.0f, 2.0f);
c.drawColor(getResources().getColor(R.color.colorPrimary));
iv.getChildAt(0).draw(c);
// Do whatever you want with your bitmap
saveBitmap(bitmap);
}
To save the bitmap
public void saveBitmap(Bitmap bitmap) {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "SidduInvoices");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
// Do something on success
} else {
// Do something else on failure
}
File imagePath = new File(Environment.getExternalStorageDirectory() + "/SidduInvoices/Siddus.png");
if(imagePath.exists())
{
imagePath=new File(Environment.getExternalStorageDirectory() + "/SidduInvoices/Siddus"+custamername.getText().toString()+".png");
}
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
progressBar.cancel();
final File finalImagePath = imagePath;
new SweetAlertDialog(this, SweetAlertDialog.SUCCESS_TYPE)
.setTitleText("Saved")
.setContentText("Do you want to share this with whatsapp")
.setCancelText("No,cancel !")
.setConfirmText("Yes,share it!")
.showCancelButton(true)
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sweetAlertDialog) {
sweetAlertDialog.cancel();
shareImage(finalImagePath);
}
})
.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sDialog) {
sDialog.cancel();
}
})
.show();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
You need get the total width and height of the scrollview, or you created viewBitmap is too small to contain the full content of the scrollview.
check this link
Android: Total height of ScrollView
The issue here is that the only actual pixel content that ever exists is that which is visible on the display screen. Android and other mobile platforms are very careful about memory use and one of the ways a scrolling view can maintain performance is to not draw anything that is offscreen. So there is no "full" bitmap anywhere -- the memory containing the content that moves offscreen is recycled.

Categories

Resources