Android camera pre-start preview for faster camera use -
i using qrcodereaderview https://github.com/dlazaro66/qrcodereaderview implementing own qr code scanner , works camera still starts slow (3-4 seconds) , came idea pre start previewing camera before using (keeping camera open when focus on fragment has button start scanning opened right away when needed) , tried seems don't understand concept , still starts slow. here code qrcodereaderview:
import com.google.zxing.binarybitmap; import com.google.zxing.checksumexception; import com.google.zxing.formatexception; import com.google.zxing.notfoundexception; import com.google.zxing.planaryuvluminancesource; import com.google.zxing.result; import com.google.zxing.resultpoint; import com.google.zxing.client.android.camera.open.cameramanager; import com.google.zxing.common.hybridbinarizer; import com.google.zxing.qrcode.qrcodereader; import java.io.ioexception; public class qrcodereaderview extends surfaceview implements surfaceholder.callback, camera.previewcallback { public interface onqrcodereadlistener { public void onqrcoderead(string text, pointf[] points); public void cameranotfound(); public void qrcodenotfoundoncamimage(); } private onqrcodereadlistener monqrcodereadlistener; private static final string tag = qrcodereaderview.class.getname(); private qrcodereader mqrcodereader; private int mpreviewwidth; private int mpreviewheight; private surfaceholder mholder; private cameramanager mcameramanager; public qrcodereaderview(context context) { super(context); init(); } public qrcodereaderview(context context, attributeset attrs) { super(context, attrs); init(); } public void setonqrcodereadlistener(onqrcodereadlistener onqrcodereadlistener) { monqrcodereadlistener = onqrcodereadlistener; } public cameramanager getcameramanager() { return mcameramanager; } @suppresswarnings("deprecation") private void init() { if (checkcamerahardware(getcontext())) { mcameramanager = new cameramanager(getcontext()); mholder = this.getholder(); mholder.addcallback(this); mholder.settype(surfaceholder.surface_type_push_buffers); // need set flag despite it's deprecated } else { log.e(tag, "error: camera not found"); if (monqrcodereadlistener != null) { monqrcodereadlistener.cameranotfound(); } } } /** * ************************************************* * surfaceholder.callback,camera.previewcallback * ************************************************** */ @override public void surfacecreated(surfaceholder holder) { try { // indicate camera, our view dimensions mcameramanager.opendriver(holder, this.getwidth(), this.getheight()); } catch (ioexception e) { log.w(tag, "can not opendriver: " + e.getmessage()); mcameramanager.closedriver(); } try { mqrcodereader = new qrcodereader(); mcameramanager.startpreview(); } catch (exception e) { log.e(tag, "exception: " + e.getmessage()); mcameramanager.closedriver(); } } @override public void surfacedestroyed(surfaceholder holder) { log.d(tag, "surfacedestroyed"); mcameramanager.getcamera().setpreviewcallback(null); mcameramanager.getcamera().stoppreview(); mcameramanager.getcamera().release(); mcameramanager.closedriver(); } // called when camera take frame @override public void onpreviewframe(byte[] data, camera camera) { planaryuvluminancesource source = mcameramanager.buildluminancesource(data, mpreviewwidth, mpreviewheight); hybridbinarizer hybbin = new hybridbinarizer(source); binarybitmap bitmap = new binarybitmap(hybbin); try { result result = mqrcodereader.decode(bitmap); // notify found qrcode if (monqrcodereadlistener != null) { // transform resultpoints view coordinates pointf[] transformedpoints = transformtoviewcoordinates(result.getresultpoints()); monqrcodereadlistener.onqrcoderead(result.gettext(), transformedpoints); } } catch (checksumexception e) { log.d(tag, "checksumexception"); e.printstacktrace(); } catch (notfoundexception e) { // notify qr not found if (monqrcodereadlistener != null) { monqrcodereadlistener.qrcodenotfoundoncamimage(); } } catch (formatexception e) { log.d(tag, "formatexception"); e.printstacktrace(); } { mqrcodereader.reset(); } } @override public void surfacechanged(surfaceholder holder, int format, int width, int height) { log.d(tag, "surfacechanged"); if (mholder.getsurface() == null) { log.e(tag, "error: preview surface not exist"); return; } //preview_width = width; //preview_height = height; mpreviewwidth = mcameramanager.getpreviewsize().x; mpreviewheight = mcameramanager.getpreviewsize().y; mcameramanager.stoppreview(); mcameramanager.getcamera().setpreviewcallback(this); mcameramanager.getcamera().setdisplayorientation(90); // portrait mode mcameramanager.startpreview(); } /** * transform result surfaceview coordinates * <p/> * method needed because coordinates given in landscape camera coordinates. * working transform operations aren't explained * <p/> * todo re-write method explaining each single value * * @return new pointf array transformed points */ private pointf[] transformtoviewcoordinates(resultpoint[] resultpoints) { pointf[] transformedpoints = new pointf[resultpoints.length]; int index = 0; if (resultpoints != null) { float previewx = mcameramanager.getpreviewsize().x; float previewy = mcameramanager.getpreviewsize().y; float scalex = this.getwidth() / previewy; float scaley = this.getheight() / previewx; (resultpoint point : resultpoints) { pointf tmppoint = new pointf((previewy - point.gety()) * scalex, point.getx() * scaley); transformedpoints[index] = tmppoint; index++; } } return transformedpoints; } /** * check if device has camera */ private boolean checkcamerahardware(context context) { if (context.getpackagemanager().hassystemfeature(packagemanager.feature_camera)) { // device has camera return true; } else if (context.getpackagemanager().hassystemfeature(packagemanager.feature_camera_front)) { // device has front camera return true; } else if (context.getpackagemanager().hassystemfeature(packagemanager.feature_camera_any)) { // device has camera return true; } else { // no camera on device return false; } } }
and here fragment uses it:
package com.breadwallet.presenter.fragments; import com.breadwallet.r; import com.breadwallet.presenter.activities.scanresultactivity; import com.breadwallet.tools.animation.springanimator; import com.breadwallet.tools.qrcode.qrcodereaderview; public class mainfragmentdecoder extends fragment implements qrcodereaderview.onqrcodereadlistener { public static final string tag = "mainfragmentdecoder"; private boolean accessgranted = true; private textview mytextview; private static qrcodereaderview mydecoderview; private imageview camera_guide_image; private intent intent; public static mainfragmentdecoder mainfragmentdecoder; private relativelayout layout; public mainfragmentdecoder() { mainfragmentdecoder = this; } @override public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) { view rootview = inflater.inflate(r.layout.fragment_decoder, container, false); intent = new intent(getactivity(), scanresultactivity.class); mytextview = (textview) rootview.findviewbyid(r.id.exampletextview); camera_guide_image = (imageview) rootview.findviewbyid(r.id.camera_guide_image); springanimator.showexpandcameraguide(camera_guide_image); // inflate layout fragment return rootview; } @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); layout = (relativelayout) getview().findviewbyid(r.id.fragment_decoder_layout); mydecoderview = new qrcodereaderview(getactivity().getapplicationcontext()); mydecoderview.setonqrcodereadlistener(mainfragmentdecoder); if (mydecoderview != null) mydecoderview.getcameramanager().startpreview(); } /** * called when qr decoded * "text" : text encoded in qr * "points" : points qr control points placed */ @override public void onqrcoderead(string text, pointf[] points) { synchronized (this) { if (accessgranted) { new handler().postdelayed(new runnable() { @override public void run() { accessgranted = true; } }, 300); accessgranted = false; // log.e(tag, "activity started!!!!!"); intent.putextra("result", text); startactivity(intent); } } } // called when device have no camera @override public void cameranotfound() { log.d(tag, "no camera found!"); } // called when there's no qr codes in camera preview image @override public void qrcodenotfoundoncamimage() { // log.d(tag, "no qr code found!"); } @override public void onresume() { super.onresume(); new cameraopenertask().execute(); } @override public void onpause() { super.onpause(); log.e(tag, "in onpause"); mydecoderview.getcameramanager().stoppreview(); layout.removeview(mydecoderview); } private class cameraopenertask extends asynctask { @override protected object doinbackground(object[] params) { return null; } @override protected void onpostexecute(object o) { new handler().postdelayed(new runnable() { @override public void run() { layout.addview(mydecoderview, 0); } }, 1300); log.e(tag, "the camera started"); } } public void stopcamera() { if (mydecoderview != null) { mydecoderview.getcameramanager().stoppreview(); } mydecoderview = null; } }
i tried:
- camera.startpreview() earlier using it.
- pre-create mydecoderview , make visible when pressing button still takes 3-4 seconds start it.
here's suffering similar problem:
the startpreview function slow, work around?
have tried of these workarounds?
Comments
Post a Comment