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

Payment information shows nothing in one page checkout page magento -

tcpdump - How to check if server received packet (acknowledged) -