android - Black edges around the taken screenshot -
i'm following example :
package com.mtsahakis.mediaprojectiondemo; import android.app.activity; import android.content.context; import android.content.intent; import android.graphics.bitmap; import android.graphics.bitmap.compressformat; import android.graphics.pixelformat; import android.graphics.point; import android.hardware.display.displaymanager; import android.hardware.display.virtualdisplay; import android.media.image; import android.media.imagereader; import android.media.projection.mediaprojection; import android.media.projection.mediaprojectionmanager; import android.os.bundle; import android.os.handler; import android.os.looper; import android.util.displaymetrics; import android.util.log; import android.view.display; import android.view.orientationeventlistener; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.nio.bytebuffer; public class screencaptureimageactivity extends activity { private static final string tag = screencaptureimageactivity.class.getname(); private static final int request_code = 100; private static string store_directory; private static int images_produced; private static final string screencap_name = "screencap"; private static final int virtual_display_flags = displaymanager.virtual_display_flag_own_content_only | displaymanager.virtual_display_flag_public; private static mediaprojection smediaprojection; private mediaprojectionmanager mprojectionmanager; private imagereader mimagereader; private handler mhandler; private display mdisplay; private virtualdisplay mvirtualdisplay; private int mdensity; private int mwidth; private int mheight; private int mrotation; private orientationchangecallback morientationchangecallback; private class imageavailablelistener implements imagereader.onimageavailablelistener { @override public void onimageavailable(imagereader reader) { image image = null; fileoutputstream fos = null; bitmap bitmap = null; try { image = mimagereader.acquirelatestimage(); if (image != null) { image.plane[] planes = image.getplanes(); bytebuffer buffer = planes[0].getbuffer(); int pixelstride = planes[0].getpixelstride(); int rowstride = planes[0].getrowstride(); int rowpadding = rowstride - pixelstride * mwidth; // create bitmap bitmap = bitmap.createbitmap(mwidth + rowpadding / pixelstride, mheight, bitmap.config.argb_8888); bitmap.copypixelsfrombuffer(buffer); // write bitmap file fos = new fileoutputstream(store_directory + "/myscreen_" + images_produced + ".png"); bitmap.compress(compressformat.jpeg, 100, fos); images_produced++; log.e(tag, "captured image: " + images_produced); } } catch (exception e) { e.printstacktrace(); } { if (fos!=null) { try { fos.close(); } catch (ioexception ioe) { ioe.printstacktrace(); } } if (bitmap!=null) { bitmap.recycle(); } if (image!=null) { image.close(); } } } } private class orientationchangecallback extends orientationeventlistener { public orientationchangecallback(context context) { super(context); } @override public void onorientationchanged(int orientation) { synchronized (this) { final int rotation = mdisplay.getrotation(); if (rotation != mrotation) { mrotation = rotation; try { // clean if(mvirtualdisplay != null) mvirtualdisplay.release(); if(mimagereader != null) mimagereader.setonimageavailablelistener(null, null); // re-create virtual display depending on device width / height createvirtualdisplay(); } catch (exception e) { e.printstacktrace(); } } } } } private class mediaprojectionstopcallback extends mediaprojection.callback { @override public void onstop() { log.e("screencapture", "stopping projection."); mhandler.post(new runnable() { @override public void run() { if(mvirtualdisplay != null) mvirtualdisplay.release(); if(mimagereader != null) mimagereader.setonimageavailablelistener(null, null); if(morientationchangecallback != null) morientationchangecallback.disable(); smediaprojection.unregistercallback(mediaprojectionstopcallback.this); } }); } } /****************************************** activity lifecycle methods ************************/ @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); // call projection manager mprojectionmanager = (mediaprojectionmanager) getsystemservice(context.media_projection_service); // start projection button startbutton = (button)findviewbyid(r.id.startbutton); startbutton.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { startprojection(); } }); // stop projection button stopbutton = (button)findviewbyid(r.id.stopbutton); stopbutton.setonclicklistener(new onclicklistener() { @override public void onclick(view v) { stopprojection(); } }); // start capture handling thread new thread() { @override public void run() { looper.prepare(); mhandler = new handler(); looper.loop(); } }.start(); } @override protected void onactivityresult(int requestcode, int resultcode, intent data) { if (requestcode == request_code) { smediaprojection = mprojectionmanager.getmediaprojection(resultcode, data); if (smediaprojection != null) { file externalfilesdir = getexternalfilesdir(null); if (externalfilesdir != null) { store_directory = externalfilesdir.getabsolutepath() + "/screenshots/"; file storedirectory = new file(store_directory); if (!storedirectory.exists()) { boolean success = storedirectory.mkdirs(); if (!success) { log.e(tag, "failed create file storage directory."); return; } } } else { log.e(tag, "failed create file storage directory, getexternalfilesdir null."); return; } // display metrics displaymetrics metrics = getresources().getdisplaymetrics(); mdensity = metrics.densitydpi; mdisplay = getwindowmanager().getdefaultdisplay(); // create virtual display depending on device width / height createvirtualdisplay(); // register orientation change callback morientationchangecallback = new orientationchangecallback(this); if (morientationchangecallback.candetectorientation()) { morientationchangecallback.enable(); } // register media projection stop callback smediaprojection.registercallback(new mediaprojectionstopcallback(), mhandler); } } } /****************************************** ui widget callbacks *******************************/ private void startprojection() { startactivityforresult(mprojectionmanager.createscreencaptureintent(), request_code); } private void stopprojection() { mhandler.post(new runnable() { @override public void run() { if (smediaprojection != null) { smediaprojection.stop(); } } }); } /****************************************** factoring virtual display creation ****************/ private void createvirtualdisplay() { // width , height point size = new point(); mdisplay.getsize(size); mwidth = size.x; mheight = size.y; // start capture reader mimagereader = imagereader.newinstance(mwidth, mheight, pixelformat.rgba_8888, 2); mvirtualdisplay = smediaprojection.createvirtualdisplay(screencap_name, mwidth, mheight, mdensity, virtual_display_flags, mimagereader.getsurface(), null, mhandler); mimagereader.setonimageavailablelistener(new imageavailablelistener(), mhandler); } }
to take screenshot on android ver >=21
.
the problem example once take screenshot , there black edges on top
, right
& bottom
of image
.
i can't see problem since given width
, height
both virtualdisplay
, bitmap
correct, i'm missing here?
problem size of virtual display.
mdisplay.getsize(size);
may return different real size of device if device have virtual navigation bar (usually swipe bottom of screen display it).
mdisplay.getrealsize(size);
will fix problem black edges.
Comments
Post a Comment