Null pointer on creating a Bitmap - android

I'm trying to screenshot a ScrollView and simply copy+pasted the solution from here: Taking a "screenshot" of a specific layout in Android . Unfortunately I'm getting a NP # Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
My XML is
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/scrollingProfile"
android:layout_width="match_parent"
android:fillViewport="true"
android:layout_height="wrap_content"
android:background="#drawable/tile_tan_repeat">
<LinearLayout
android:id="#+id/paidLayoutLinearParent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--......-->
</LinearLayout>
</ScrollView>
Anyone have any ideas of why this is happening? I've never really worked with saving files like this so debugging this code is pretty unfamiliar to me.
Thank you!
Edit:This is the code I'm using
public void onClick(View v) {
if(v.getId()==R.id.screenshot){//source: https://stackoverflow.com/questions/10650049/taking-a-screenshot-of-a-specific-layout-in-android
View u = findViewById(R.id.scrollingProfilePaid);
u.setDrawingCacheEnabled(true);
ScrollView z = (ScrollView) findViewById(R.id.scrollingProfilePaid);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
u.layout(0, 0, totalWidth, totalHeight);
u.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
u.setDrawingCacheEnabled(false);
//Save bitmap
String extr = Environment.getExternalStorageDirectory().toString() + File.separator + "Folder";
//String fileName = new SimpleDateFormat("yyyyMMddhhmm'profile.jpg'").format(new Date());
String fileName = "profile.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(getContentResolver(), b, "Screen", "screen");
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

just put the code inside
scrollview.post(
new Runnable()
{
#Override
public void run()
{
//this method will call after scrollview's onDraw method
// so the view is ready to generarte bitmap at this point
//put here your screen shot code
}
});

Related

Listview Items not getting displayed when converting XML Layout to bitmap image

I've been trying to convert an XML Layout to bitmap image. When i click on the convert button, image is being generated. But my ListView items are not getting displayed. How can i do that?
Following is my code
mView = findViewById(R.id.f_view);
mButton = (Button) findViewById(R.id.button1);
mButton.setOnClickListener(this);
mView.setDrawingCacheEnabled(true);
mView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
mView.buildDrawingCache(true);
}
#Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
Bitmap b = Bitmap.createBitmap(mView.getDrawingCache());
mView.setDrawingCacheEnabled(false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Expense Calculator" + File.separator + "Expense.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
Toast.makeText(null, getApplicationContext()+ "Image Generated", Toast.LENGTH_SHORT).show();
fo.close();
} catch (Exception e) {
}
//finish();
}
}
and my xml code is as follows
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<include android:id="#+id/f_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
layout="#layout/view_expense"
android:layout_above="#id/button1"/>
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="54dp"
android:background="#drawable/cimage" />
</RelativeLayout>
What should i do to get my listview items displayed? Can Someone help me please?
Thanks
Enable drawing cache only when you want to get Bitmap from on-click.
mView.buildDrawingCache(true);
Remove above line form onCreate() methdod.
You Need to disable DrawingCache immediately after generating Bitmap from View
like below code:
mView.destroyDrawingCache();
Try Below onClick Code:
#Override
public void onClick(View v) {
if (v.getId() == R.id.button1) {
mView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mView.getDrawingCache());
mView.setDrawingCacheEnabled(false);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
b.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Expense Calculator" + File.separator + "Expense.jpg");
try {
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
Toast.makeText(null, getApplicationContext()+ "Image Generated", Toast.LENGTH_SHORT).show();
fo.close();
} catch (Exception e) {
}
//finish();
}
Use Below method to get bitmap from view you can pass view in this method :
public Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
view.layout(0, 0, view.getLayoutParams().width, view.getLayoutParams().height);
view.draw(canvas);
return returnedBitmap;
}

How to capture a complete view of an Activity Screen in Android

I am using a scroll View in my activity.I want to share the whole activity screen but not able to do that.Am able to share the visible part of the screen but not the full screen of the activity.Is it possible to take the screenshot of the full activity.I have tried like this but its sharing only the visible part of the activity.Plz help me out of this.Thank You
ShareImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//View v1 = getWindow().getDecorView();
View v1 = findViewById(android.R.id.content);
v1.setDrawingCacheEnabled(true);
myBitmap = v1.getDrawingCache();
saveBitmap(myBitmap);
}
});
Saving the Screenshot taken ::
public void saveBitmap(Bitmap bitmap) {
String filePath = Environment.getExternalStorageDirectory()
+ File.separator + "Pictures/screencapture.png";
File imagePath = new File(filePath);
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
share(filePath);
} catch (FileNotFoundException e) {
Log.e("exception1", e.getMessage(), e);
} catch (IOException e) {
Log.e("exception2", e.getMessage(), e);
}
}
try this:
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.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}

Webview unusable after draw method called

I want to extract webview screenshot (even if there is a scroll) and to save it.
My problem is after webview.draw() method called, webview is now an image an is unusable as a webview.
If there a way to prevent that behavior ?
Important : I can't just reload webview because user enters fields.
Here's my code :
protected void onClicked() {
mWebView.measure(View.MeasureSpec.makeMeasureSpec(
View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
mWebView.layout(0, 0, mWebView.getMeasuredWidth(),
mWebView.getMeasuredHeight());
mWebView.setDrawingCacheEnabled(true);
mWebView.buildDrawingCache();
generateWebViewCapture();
}
/**
* Create capture of all webview.
*/
#Background
void generateWebViewCapture() {
Bitmap bm = Bitmap.createBitmap(mWebView.getMeasuredWidth(),
mWebView.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bm);
Paint paint = new Paint();
int iHeight = bm.getHeight();
canvas.drawBitmap(bm, 0, iHeight, paint);
mWebView.draw(canvas);
runOnUiThread(new Runnable() {
#Override
public void run() {
mWebView.setDrawingCacheEnabled(false);
mWebView.invalidate();
}
});
try {
String path = getReportPath();
File file = new File(path, "/report-"+System.currentTimeMillis()+".png");
OutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
}
EDIT :
To fix the problem, remove that line :
mWebView.layout(0, 0, mWebView.getMeasuredWidth(),
mWebView.getMeasuredHeight());
Just mWebView.setDrawingCacheEnabled(false) after you get the bitmap!
mWebView.setDrawingCacheEnabled(true);
// remove mWebView.buildDrawingCache();
Bitmap bm= mWebView.getDrawingCache();
//remove generateWebViewCapture();
try {
String path = getReportPath();
File file = new File(path, "/report-"+System.currentTimeMillis()+".png");
OutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
mWebView.setDrawingCacheEnabled(false);
This code is worked on my mobile:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.testm);
final WebView mWebView = (WebView) findViewById(R.id.webview);
mWebView.loadUrl("http://www.csdn.net/");
findViewById(R.id.iv_0).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mWebView.setDrawingCacheEnabled(true);
// remove mWebView.buildDrawingCache();
Bitmap bm= mWebView.getDrawingCache();
//remove generateWebViewCapture();
try {
String path = getFilesDir().getPath();
File file = new File(path, "/report-"+System.currentTimeMillis()+".png");
OutputStream fOut = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
e.printStackTrace();
}
mWebView.setDrawingCacheEnabled(false);
}
});
}
}
It does not work on Android R.
WebView.enableSlowWholeDocumentDraw()
Add ScrollView, It works.
<ScrollView
android:layout_marginStart="#dimen/margin_8"
android:layout_marginEnd="#dimen/margin_8"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView
android:id="#+id/web_view"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</ScrollView>

Android : taking Screenshot of the selected area programmatically

My code is as follow :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button upload = (Button) findViewById(R.id.screeshotdButton);
upload.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
folderCheck();
}
});
}
private void folderCheck(){
File folder = new File(Environment.getExternalStorageDirectory() + "/cloze_screenshots");
boolean success = true;
// If the folder cloze not exist, create one
if (!folder.exists()) {
success = folder.mkdir();
}else{
ScreenShot();
}
// If mkdir successful
if (success) {
ScreenShot();
} else {
Log.e("mkdir_fail","QQ");
}
}
private void ScreenShot(){
String filePath = Environment.getExternalStorageDirectory()+ "/cloze_screenshots/temp.png";
// create bitmap screen capture
Bitmap bitmap;
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
File imageFile = new File(filePath);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
Toast.makeText(this, "Success", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This code can take a fullscreen screenshot , but I want to take a screenshot on specific area (For example, the left block on the screen ) programmatically after I press the button.
Any code or suggestion will be appreciate.
You can wrap the contents in a layout for example LinearLayout and follow the above code for taking screenshot by using the methods on the wrapped layout.
Bitmap bitmap;
ViewGroup v1 = findViewById(R.id.layout_id);
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
Below method takes snapshot of given view which is adjustable by means of height and width then returns bitmap of it
public static Bitmap takeSnapshot(View givenView, int width, int height) {
Bitmap bm = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas snap = new Canvas(bm);
givenView.layout(0, 0, givenView.getLayoutParams().width, givenView.getLayoutParams().height);
givenView.draw(snap);
return bm; }

Taking android screen shot of whole screen

My application has a list view in relative layout. Now I need to take a screen shot of the entire layout including all the content available in the list view and also other contents like button and text view showing in the layout. But my code takes only the visible part of the screen. Here the view is parent layout.
public void screen(){
View v1 = findViewById(R.id.screenRoot);
rel.layout(0, 0, rel.getMeasuredWidth(),rel.getMeasuredHeight());
View v = v1.getRootView();
v.setDrawingCacheEnabled(true);
/* v.measure(MeasureSpec.makeMeasureSpec(w, w),
MeasureSpec.makeMeasureSpec(h, h));*/
// v.layout(0, 0, rel.getWidth(), rel.getHeight());
v.buildDrawingCache(true);
System.out.println("rel "+rel.getHeight()+" "+v.getHeight());
Bitmap b = v.getDrawingCache();
v.setDrawingCacheEnabled(false);
String extr = Environment.getExternalStorageDirectory().toString();
File myPath = new File(extr, "tiket"+".jpg");
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(getContentResolver(), b, "Screen", "screen");
System.out.println("my path "+myPath+" "+fos);
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Image Captured Successfully", 0).show();
}
Call getBitmapFromView from your Click event or any thing.
R.id.root is my main RelativeLayout So you can pass you main layout.
LayoutInflater inflater = (LayoutInflater)this.getSystemService(LAYOUT_INFLATER_SERVICE);
RelativeLayout root = (RelativeLayout)inflater.inflate(R.layout.youlayourfile,null);
root.setDrawingCacheEnabled(true);
Bitmap bmp = getBitmapFromView(this.getWindow().getDecorView().findViewById(R.id.root).getRootView());
URI uri = storPrintFile(bmp);
This function returns the Bitmap of your layout. Now you just need to store the bitmap into your device and anywhere else.
public Bitmap getBitmapFromView(View v) {
v.setLayoutParams(new LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Storing bitmap into device.
public URI storPrintFile(Bitmap bitmapToStore){
ContextWrapper cw = new ContextWrapper(getApplicationContext());
String path = cw.getDir("CapturedImages",Context.MODE_PRIVATE).getPath();
File file = new File(path);
boolean isFileCreated = false;
if (!file.exists()) {
isFileCreated = file.mkdir();
System.out.println("Directory created in Internal Storage is :" + path);
}
String current = "Screen.jpg";//uniqueId.replace(" ", "-").replace(":", "-") + ".jpeg";
System.out.println("Internal Storage path is : " + current);
File mypath = new File(file, current);
try {
FileOutputStream out = new FileOutputStream(mypath);
bitmapToStore.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return mypath.toURI();
}

Categories

Resources