android - Picture convertion colours onPreviewFrame with NV21 to JPEG -


for 15 days 'm stuck on recording of frames in event onpreviewframe android camera . goal simple, want record 5 consecutive images @ click of button. not want block preview of camera , use previewframe . during recording of image in jpeg on sd card green , pink many horizontal bars. term send list of byte [] on web api.

i lot of research , trying change picturesize , previewsize nothing changes .

another option not go through recording video , extract frame of ?

here code in fragment :

package rocketweb.com.videocatcher.fragment;    import android.content.context;  import android.graphics.bitmap;  import android.graphics.bitmapfactory;  import android.graphics.imageformat;  import android.graphics.rect;  import android.graphics.yuvimage;  import android.hardware.camera;  import android.os.asynctask;  import android.os.bundle;  import android.os.environment;  import android.util.displaymetrics;  import android.util.log;  import android.view.display;  import android.view.layoutinflater;  import android.view.surface;  import android.view.surfaceholder;  import android.view.surfaceview;  import android.view.view;  import android.view.viewgroup;  import android.view.windowmanager;  import android.widget.button;  import android.widget.framelayout;  import android.widget.toast;    import org.apache.http.httpresponse;  import org.apache.http.client.clientprotocolexception;  import org.apache.http.client.httpclient;  import org.apache.http.client.responsehandler;  import org.apache.http.client.methods.httppost;  import org.apache.http.entity.mime.content.bytearraybody;  import org.apache.http.impl.client.basicresponsehandler;  import org.apache.http.impl.client.defaulthttpclient;    import java.io.bufferedreader;  import java.io.bytearrayoutputstream;  import java.io.datainputstream;  import java.io.file;  import java.io.filenotfoundexception;  import java.io.fileoutputstream;  import java.io.ioexception;  import java.io.inputstreamreader;  import java.nio.charset.charset;  import java.util.arraylist;  import java.util.list;  import rocketweb.com.videocatcher.r;  import rocketweb.com.videocatcher.utilities.imagehelper;    import org.apache.http.entity.mime.multipartentity;  import org.apache.http.entity.mime.content.stringbody;  import org.apache.http.entity.mime.httpmultipartmode;  import org.apache.http.protocol.basichttpcontext;  import org.apache.http.protocol.httpcontext;    /**   * created bastien on 15/03/2015.   */  public class camerafragment extends basefragment  {        private camera mcamera;      private camerapreview mpreview;      private view mcameraview;      private list<byte[]> imagesframe;      private boolean activeframecapture = false;        public camerafragment(){          super();      }        public static camerafragment newinstance(int sectionnumber) {          camerafragment fragment = new camerafragment();          bundle args = new bundle();          args.putint(arg_section_number, sectionnumber);          fragment.setarguments(args);          return fragment;      }        @override      public view oncreateview(layoutinflater inflater, viewgroup container, bundle savedinstancestate) {          view view = inflater.inflate(r.layout.fragment_video_catcher, container, false);          boolean opened = safecameraopeninview(view);            if(opened == false){              log.d("camera", "error, camera failed open");              return view;          }            button capturebutton = (button) view.findviewbyid(r.id.button_capture);          capturebutton.setonclicklistener(                  new view.onclicklistener() {                      @override                      public void onclick(view v) {                          activeframecapture = !activeframecapture;                      }                  }          );            imagesframe = new arraylist<byte[]>(){};          return view;      }        private boolean safecameraopeninview(view view) {          boolean qopened = false;          releasecameraandpreview();          mcamera = getcamerainstance();          mcameraview = view;          qopened = (mcamera != null);            if(qopened == true){              mpreview = new camerapreview(getactivity().getbasecontext(), mcamera,view);              framelayout preview = (framelayout) view.findviewbyid(r.id.camera_preview);              preview.addview(mpreview);              mpreview.startcamerapreview();          }          return qopened;      }        public static camera getcamerainstance(){          camera c = null;          try {              c = camera.open(); // attempt camera instance          }          catch (exception e){              e.printstacktrace();          }          return c; // returns null if camera unavailable      }        @override      public void onpause() {          super.onpause();      }        @override      public void ondestroy() {          super.ondestroy();          releasecameraandpreview();      }        private void releasecameraandpreview() {            if (mcamera != null) {              mcamera.stoppreview();              mcamera.release();              mcamera = null;          }          if(mpreview != null){              mpreview.destroydrawingcache();              mpreview.mcamera = null;          }      }        class camerapreview extends surfaceview implements surfaceholder.callback {            private surfaceholder mholder;          private camera mcamera;          private context mcontext;          private camera.size mpreviewsize;          private list<camera.size> msupportedpreviewsizes;          private list<string> msupportedflashmodes;          private list<camera.size> msupportedsizepicture;          private view mcameraview;            public camerapreview(context context, camera camera, view cameraview) {              super(context);                // capture context              mcameraview = cameraview;              mcontext = context;              setcamera(camera);                // install surfaceholder.callback notified when              // underlying surface created , destroyed.              mholder = getholder();              mholder.addcallback(this);              mholder.setkeepscreenon(true);              // deprecated setting, required on android versions prior 3.0              mholder.settype(surfaceholder.surface_type_push_buffers);                mcamera.setpreviewcallback(new camera.previewcallback() {                  public void onpreviewframe(byte[] data, camera camera) {                      if (activeframecapture && imagesframe.size() <= 5) {                          camera.parameters parameters = camera.getparameters();                          camera.size size = parameters.getpreviewsize();                          yuvimage im = new yuvimage(data, imageformat.nv21, size.width,size.height, null);                          rect r = new rect(0,0,size.width,size.height);                          bytearrayoutputstream baos = new bytearrayoutputstream();                          im.compresstojpeg(r, parameters.getjpegquality(), baos);                            try{                              fileoutputstream output = new fileoutputstream(string.format(                                      "/sdcard/%s_%d.jpg", "test", system.currenttimemillis()));                              output.write(baos.tobytearray());                              output.flush();                              output.close();                          }catch(filenotfoundexception e)                          {                              e.printstacktrace();                          }catch(ioexception e){                              e.printstacktrace();                          }                            imagesframe.add(data);                      }                  }              });            }            public void startcamerapreview()          {              try{                  mcamera.setpreviewdisplay(mholder);                  mcamera.startpreview();              }              catch(exception e){                  e.printstacktrace();              }          }            private void setcamera(camera camera)          {              mcamera = camera;              msupportedpreviewsizes = mcamera.getparameters().getsupportedpreviewsizes();              msupportedflashmodes = mcamera.getparameters().getsupportedflashmodes();              msupportedsizepicture = mcamera.getparameters().getsupportedpicturesizes();                camera.parameters parameters = mcamera.getparameters();                // set camera auto flash mode.              if (msupportedflashmodes != null && msupportedflashmodes.contains(camera.parameters.flash_mode_auto))                  parameters.setflashmode(camera.parameters.flash_mode_auto);                mcamera.setparameters(parameters);              requestlayout();          }            public void surfacecreated(surfaceholder holder) {              try {                  mcamera.setpreviewdisplay(holder);              } catch (ioexception e) {                  e.printstacktrace();              }          }            public void surfacedestroyed(surfaceholder holder) {              if (mcamera != null){                  mcamera.setpreviewcallback(null);                  mcamera.stoppreview();                  mcamera.release();              }          }            public void surfacechanged(surfaceholder holder, int format, int w, int h) {              // if preview can change or rotate, take care of events here.              // make sure stop preview before resizing or reformatting it.                if (mholder.getsurface() == null){                  // preview surface not exist                  return;              }                // stop preview before making changes              try {                  camera.parameters parameters = mcamera.getparameters();                    // set auto-focus mode "continuous"                  parameters.setfocusmode(camera.parameters.focus_mode_continuous_picture);                    // preview size must exist.                  if(mpreviewsize != null) {                      // 0 = landscape                      // 90 = portrait                        int rotation = getactivity().getwindowmanager().getdefaultdisplay().getrotation();                      int degrees = 0;                      switch (rotation) {                          case surface.rotation_0: degrees = 90; break;                          case surface.rotation_90: degrees = 0; break;                      }                        mcamera.setdisplayorientation(degrees);                      if(degrees == 0)                          parameters.setpreviewsize(mpreviewsize.width, mpreviewsize.height);                      else                          parameters.setpreviewsize(mpreviewsize.height, mpreviewsize.width);                    }                    mcamera.setparameters(parameters);                  mcamera.startpreview();              } catch (exception e){                  e.printstacktrace();              }          }            /**           * calculate measurements of layout           * @param widthmeasurespec           * @param heightmeasurespec           */          @override          protected void onmeasure(int widthmeasurespec, int heightmeasurespec)          {              // source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails              final int width = resolvesize(getsuggestedminimumwidth(), widthmeasurespec);              final int height = resolvesize(getsuggestedminimumheight(), heightmeasurespec);              setmeasureddimension(width, height);                if (msupportedpreviewsizes != null){                  mpreviewsize = getoptimalpreviewsize(msupportedpreviewsizes, width, height);              }          }            @override          protected void onlayout(boolean changed, int left, int top, int right, int bottom)          {              // source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails              if (changed) {                  final int width = right - left;                  final int height = bottom - top;                    int previewwidth = width;                  int previewheight = height;                    if (mpreviewsize != null){                      display display = ((windowmanager)mcontext.getsystemservice(context.window_service)).getdefaultdisplay();                        switch (display.getrotation())                      {                          case surface.rotation_0:                              previewwidth = mpreviewsize.height;                              previewheight = mpreviewsize.width;                              mcamera.setdisplayorientation(90);                              break;                          case surface.rotation_90:                              previewwidth = mpreviewsize.width;                              previewheight = mpreviewsize.height;                              break;                          case surface.rotation_180:                              previewwidth = mpreviewsize.height;                              previewheight = mpreviewsize.width;                              break;                          case surface.rotation_270:                              previewwidth = mpreviewsize.width;                              previewheight = mpreviewsize.height;                              mcamera.setdisplayorientation(180);                              break;                      }                  }                    final int scaledchildheight = previewheight * width / previewwidth;                  mcameraview.layout(0, height - scaledchildheight, width, height);              }          }            private camera.size getoptimalpreviewsize(list<camera.size> sizes, int width, int height)          {              // source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails              camera.size optimalsize = null;                final double aspect_tolerance = 0.1;              double targetratio = (double) height / width;                // try find size match suits whole screen minus menu on left.              (camera.size size : sizes){                    if (size.height != width) continue;                  double ratio = (double) size.width / size.height;                  if (ratio <= targetratio + aspect_tolerance && ratio >= targetratio - aspect_tolerance){                      optimalsize = size;                  }              }                // if cannot find 1 matches aspect ratio, ignore requirement.              if (optimalsize == null) {                  // todo : backup in case don't size.              }                return optimalsize;          }        }  }

the layout of fragment :

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"      android:orientation="vertical"      android:layout_width="fill_parent"      android:layout_height="fill_parent"      >      <framelayout          android:id="@+id/camera_preview"          android:layout_width="fill_parent"          android:layout_height="fill_parent"          android:layout_weight="1"          />          <relativelayout          android:id="@+id/innerrelativelayout"          android:layout_width="wrap_content"          android:layout_height="wrap_content"          android:layout_alignparentbottom="true" >          <button              android:id="@+id/button_capture"              android:text="capture"              android:layout_width="fill_parent"              android:layout_height="50dp"              android:layout_margin="10dp"              android:layout_gravity="bottom"              />      </relativelayout>  </relativelayout>

my project configuration :

apply plugin: 'com.android.application'    android {      compilesdkversion 21      buildtoolsversion "21.1.2"        defaultconfig {          applicationid "rocketweb.com.videocatcher"          minsdkversion 15          targetsdkversion 21          versioncode 1          versionname "1.0"      }      buildtypes {          release {              minifyenabled false              proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro'          }      }        packagingoptions {          exclude 'meta-inf/dependencies.txt'          exclude 'meta-inf/notice.txt'          exclude 'meta-inf/license.txt'      }  }    dependencies {      compile filetree(dir: 'libs', include: ['*.jar'])      compile 'com.android.support:appcompat-v7:21.0.3'      compile 'com.google.code.gson:gson:2.3.1'      compile "org.apache.httpcomponents:httpmime:4.2.3"  }

end exemple of image result : dropbox link pictures

i can upload android studio project if needed. thank in advance help

i think problem might when try setpreviewsize() according rotation of camera. please make sure set supported preview size contained in parameters.getsupportedpreviewsizes() without swapping dimensions.

i suspect problem trying swap supported (width,height) pair , setting camera , it's being rejected capture parameter, still being improperly used when telling new yuvimage(...) constructor how interpret image byte array.


Comments

Popular posts from this blog

javascript - AngularJS custom datepicker directive -

javascript - jQuery date picker - Disable dates after the selection from the first date picker -