I'm trying to take a screenshot of the currently playing video. I'm trying with code that successfully takes a screenshot of web view but get not success in taking photo of currently playing video.
The code as follow for web view.
WebView w = new WebView(this);
w.setWebViewClient(new WebViewClient()
{
public void onPageFinished(WebView view, String url)
{
Picture picture = view.capturePicture();
Bitmap b = Bitmap.createBitmap( picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas( b );
picture.draw( c );
FileOutputStream fos = null;
try {
fos = new FileOutputStream( "/sdcard/yahoo_" +System.currentTimeMillis() + ".jpg" );
if ( fos != null )
{
b.compress(Bitmap.CompressFormat.JPEG, 90, fos );
fos.close();
}
} catch( Exception e )
{
//...
}
}
});
setContentView( w );
w.loadUrl( "http://www.yahoo.com");
To expand on 66CLSjY's answer, FFmpegMediaMetadataRetriever has the same interface as MediaMetadataRetriever but it uses FFmpeg as the backend. If the default configuration won't work with your video format you can enable/disable codecs by recompiling. Here is some sample code:
FFmpegMediaMetadataRetriever mmr = new FFmpegMediaMetadataRetriever();
mmr.setDataSource(mUri);
mmr.extractMetadata(FFmpegMediaMetadataRetriever.METADATA_KEY_VIDEO_CODEC);
Bitmap b = getFrameAtTime(3000);
mmr.release();
try this it will gives bitmap for your app screen
View v = view.getRootView();
v.setDrawingCacheEnabled(true);
Bitmap b = v.getDrawingCache();
This works for me:
First a method to convert your view into a bitmap
public static 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;
}
Then save into the SD, for example:
static private boolean saveImage(Bitmap bm, String absolutePath)
{
FileOutputStream fos = null;
try
{
String absolutePath = "your path"
File file = new File(absolutePath);
fos = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, fos); //PNG ignora la calidad
} catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (fos != null)
fos.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
return true;
}
Good Luck!
Related
I am taking screenshot programmatically using the following code:
public static Bitmap takeScreenshot(View view)
{
try
{
// create bitmap screen capture
view.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return bitmap;
}
catch (Throwable e)
{
CustomLogHandler.printError(e);
}
return null;
}
private static void copyFile(Bitmap bitmap)
{
File dstFile = getShareResultFile();
//Delete old file if exist.
if(dstFile.exists()) {
dstFile.delete();
}
FileOutputStream fos = null;
try
{
fos = new FileOutputStream(dstFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, fos);
fos.flush();
}
catch (Exception e) {
CustomLogHandler.printError(e);
}
finally {
if (fos != null) {
try {
fos.close();
} catch (IOException ioe) {
CustomLogHandler.printError(ioe);
}
}
}
}
There are several problem like:
Back arrow, title and share menu background color is not correct. It looks messy.
Background color of toolbar is totally changed.
Image quality is too poor and list items rounded drawable has not smooth corners.
Background of layout is not taken that I set as background of my parent layout.
I am taking the screenshot from the root view.
bitmap.compress(Bitmap.CompressFormat.JPEG, 0, fos);
First, you are saving this as a JPEG. JPEG is designed for photos, and your screenshot is not a photo.
Second, you are saving this with a quality factor of 0. JPEG uses a lossy compression algorithm, and a quality factor of 0 says "please feel free to make this image be really poor, but compress it as far as you can".
I suggest switching to:
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
PNG is a better image format for a screenshot with the contents shown in your question. I don't think PNG uses the quality factor value; I put in 100 just to indicate that you want the best possible quality.
public static Bitmap takeScreenshot(View view)
{
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
This code can save view as bitmap.
But after you update your question with save code I see that you set 0 for quality, and what you expect?
#param quality Hint to the compressor, 0-100. 0 meaning compress for
* small size, 100 meaning compress for max quality. Some
* formats, like PNG which is lossless, will ignore the
* quality setting
just use your Ctrl button + click on method name to read doc about params
the answer is set second parameter 100 instead of 0!
Try using this:
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dm.heightPixels, 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;
}
and
public void takeScreen() {
Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
File imageFile = new File(mPath);
OutputStream fout = null;
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
fout.close();
}
}
Images are saved in the external storage folder.
try this
private void captureScreen() {
View v = this.getWindow().getDecorView().findViewById(android.R.id.content);
v.setDrawingCacheEnabled(true);
Bitmap bitmap = v.getDrawingCache();
String extr = Environment.getExternalStorageDirectory().toString();
File file = new File(extr, getString(R.string.free_tiket) + ".jpg");
FileOutputStream f = null;
try {
f = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, f);
f.flush();
f.close();
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Screen", "screen");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
Basically, I want to take a screenshot of an entire scrollView. I've tried so many methods, but couldn't find the perfect one.
I've tried following:
public void takeScreenShot() {
mbitmap = getBitmapOFRootView();
createImage(mbitmap);
}
public void createImage(Bitmap bmp) {
String path = Environment.getExternalStorageDirectory().toString() + "/screenshot.jpg";
try {
FileOutputStream outputStream = new FileOutputStream(new File(path));
bmp.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public Bitmap getBitmapOFRootView() {
mScrollView.setDrawingCacheEnabled(true);
int totalHeight = mScrollView.getChildAt(0).getHeight();
int totalWidth = mScrollView.getChildAt(0).getWidth();
mScrollView.layout(0,0, totalWidth, totalHeight);
mScrollView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mScrollView.getDrawingCache());
mScrollView.setDrawingCacheEnabled(false);
return b;
}
This method almost works, but it's just showing me only 2 views and a button, other than that whole screen is black:
my xml contains so many views, it's view hierarchy is something like this:
<ScrollView>
<ConstraintLayout>
<Views>
....
<Views>
</ConstraintLayout>
</ScrollView>
I've referred so many StackOverflow post, but it didn't work.
So can anybody help me with it?
Update:
Finally found a solution for it. So, it was an issue with the background, solved it by drawing canvas over it. Like below:
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;
You should be using a canvas for the same
public static Bitmap saveBitmapFromView(View view, int width, int height) {
Bitmap bmp = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
view.layout(0, 0, view.getLayoutParams().width, view.getLayoutParams().height);
view.draw(canvas);
return bmp;
}
Taking and Sharing screenshot in android programmatically
I've searched everywhere but found this one working
takeAndShareScreenshot()
private void takeAndShareScreenshot(){
Bitmap ss = takeScreenshot();
saveBitmap(ss);
shareIt();
}
takeScreenshot()
private Bitmap takeScreenshot() {
View view = // decore view of the activity/fragment;
view.setDrawingCacheEnabled(true);
return view.getDrawingCache();
}
saveBitmap()
private void saveBitmap(Bitmap bitmap) {
// path to store screenshot and name of the file
imagePath = new File(requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + "name_of_file" + ".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
shareIt()
private void shareIt() {
try {
Uri uri = Uri.fromFile(imagePath);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/*");
String shareBody = getString(R.string.share_body_text);
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, R.string.subject);
sharingIntent.putExtra(Intent.EXTRA_TEXT, shareBody);
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
} catch (Exception e) {
e.printStackTrace();
}
}
Note:
In recent versions of android (>Marshmallow I guess), you may need `write
access to external directory`
I must be doing something wrong here with saving the image or something, as when I save it as a png, its a blank white image. When I save it as a JPEG, it's a blank black image.
The webview loads in my application after about 1 second.
.....
webView = (WebView)findViewById(R.id.webview_1);
webView.setWebViewClient(new WebViewClient() {
#Override
public void onPageFinished(WebView view, String url) {
//Bitmap b = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Bitmap b = getBitmapFromWebView(webView);
Canvas c = new Canvas(b);
view.draw(c);
try {
FileOutputStream fos = openFileOutput("test.png", Context.MODE_APPEND);
//fos = new FileOutputStream( "/sdcard/" + "page.jpg" );
if ( fos != null ) {
b.compress(Bitmap.CompressFormat.PNG, 90, fos );
fos.close();
}
}
catch( Exception e ) {
System.out.println("-----error--"+e);
}
}
});
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
webSettings.setUseWideViewPort(true);
webView.addJavascriptInterface(new WebAppInterface(this), "Android");
webView.loadUrl("file:///android_asset/World_display.html");
....
public Bitmap getBitmapFromWebView(WebView wv) {
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(wv.getDrawingCache());
webView.setDrawingCacheEnabled(false);
return bitmap;
}
Please try this:
public static Bitmap getBitmapfromView(View v) {
Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
v.draw(canvas);
return bitmap;
}
As it turns out, the webview isn't rendered until sometime after onPageFinished. All of this code being in my onCreate was saving a blank image because the webview hadn't been rendered yet.
Ended up doing this as a separate method outside onCreate:
public Bitmap getBitmapFromWebView(View v) {
webView.setDrawingCacheEnabled(true);
webView.buildDrawingCache(true);
Bitmap bitmap = Bitmap.createBitmap(v.getDrawingCache());
try {
FileOutputStream fos = openFileOutput("test.png", Context.MODE_PRIVATE);
//fos = new FileOutputStream( "/sdcard/" + "page.jpg" );
if (fos != null) {
bitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);
fos.close();
}
} catch (Exception e) {
System.out.println("-----error--" + e);
}
return bitmap;
}
And calling this method from within a "submit" button onclick in the onCreate.
I am trying to capture webview full page content as a screenshot(bitmap) in android but no luck. Tested many solutions suggested in stackoverflow and other sites. Please help.
Bitmap bitmap = Bitmap.createBitmap(webView.getWidth(), webView.getContentHeight(), Bitmap.Config.ARGB_4444);
webView.draw(new Canvas(bitmap));
You can try this :
WebView w ;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
w = new WebView(this);
w.setWebViewClient(new WebViewClient()
{
public void onPageFinished(WebView view, String url)
{
Picture picture = view.capturePicture();
Bitmap b = Bitmap.createBitmap( picture.getWidth(),
picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas( b );
picture.draw( c );
FileOutputStream fos = null;
try {
fos = new FileOutputStream( "mnt/sdcard/yahoo.jpg" );
if ( fos != null )
{
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
}
}
catch( Exception e )
{
}
}
});
setContentView(w);
w.loadUrl("http://search.yahoo.com/search?p=android");
}
I found this from hear.. click.
did you try in this way.
I have this code for take screenshot of current view, a fragment that lives into an activity, where the activity has only a background.
private File captureScreen() {
Bitmap screenshot = null;
try {
if (view != null) {
screenshot = Bitmap.createBitmap(view.getMeasuredWidth(),
view.getMeasuredHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(screenshot);
view.draw(canvas);
// save pics
File cache_dir = Environment.getExternalStorageDirectory();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
screenshot.compress(Bitmap.CompressFormat.PNG, 90, bytes);
File f = new File(cache_dir + File.separator + "screen.png");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
return f;
}
} catch (Exception e) {
// TODO
}
return null;
}
but bitmap saved is not exactly what i'm expecting.
Screenshot take only fragment elements, but not activity background. How can i include it into screenshot?
From :How to programmatically take a screenshot in Android?
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + ACCUWX.IMAGE_APPEND;
// create bitmap screen capture
Bitmap bitmap;
View v1 = mCurrentUrlMask.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
imageFile = new File(mPath);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try this. it work for me. and for you too
Call this method, passing in the outer most ViewGroup that you want a screen shot of:
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
I've used it for a while in a few different apps and haven't had any issues. Hope it vll helps