i'm having problem camera app. app has:
1) cameraactivity.class ,
2) camerapreview.class.
camerapreview
implement surfaceview
it's called cameraactivity
actual preview. (also in cameraactivity
have parameters)
now problem: when preview starting preview stretched. tried lot of things (so many cannot recall) need tell me write , where. in advance.
here cameraactivity
(not code important think)
private picturecallback mpicture = new picturecallback() { public void onpicturetaken(byte[] data, camera camera) { // replacing button after photho taken. flbtncontainer.setvisibility(view.gone); ibretake.setvisibility(view.visible); ibuse.setvisibility(view.visible); // file name of image took. filename = "img_" + new simpledateformat("yyyymmdd_hhmmss").format(new date()).tostring() + ".jpg"; // creating directory save image. sadly in older // version of android can not media catalog name file mkdir = new file(sdroot, dir); mkdir.mkdirs(); // main file save data recive camera file picturefile = new file(sdroot, dir + filename); try { fileoutputstream purge = new fileoutputstream(picturefile); purge.write(data); purge.close(); } catch (filenotfoundexception e) { log.d("dg_debug", "file not found: " + e.getmessage()); } catch (ioexception e) { log.d("dg_debug", "error accessing file: " + e.getmessage()); } // adding exif data orientation. strange reason // exifinterface class takes string instead of file. try { exif = new exifinterface("/sdcard/" + dir + filename); exif.setattribute(exifinterface.tag_orientation, "" + orientation); exif.saveattributes(); } catch (ioexception e) { e.printstacktrace(); } intent intent = new intent(cameraactivity.this, picturepreview.class); bundle extras = new bundle(); extras.putstring("imagepath", string.valueof(picturefile)); intent.putextras(extras); startactivity(intent); //sendbroadcasts let's instantly update sd card our image sendbroadcast(new intent(intent.action_media_scanner_scan_file, uri.parse("file://"+environment.getexternalstoragedirectory()))); } }; private void createcamera() { // create instance of camera mcamera = getcamerainstance(); // setting right parameters in camera camera.parameters params = mcamera.getparameters(); params.setrotation(90); mcamera.setparameters(params); // create our preview view , set content of our activity. mpreview = new camerapreview(this, mcamera); framelayout preview = (framelayout) findviewbyid(r.id.camera_preview); preview.addview(mpreview, 0); } @override protected void onresume() { super.onresume(); // test if there camera on device , if sd card // mounted. if (!checkcamerahardware(this)) { intent = new intent(this, nocamera.class); startactivity(i); finish(); } else if (!checksdcard()) { intent = new intent(this, nosdcard.class); startactivity(i); finish(); } // creating camera createcamera(); // register class listener accelerometer sensor ////sensormanager.registerlistener(this, sensormanager.getdefaultsensor(sensor.type_accelerometer), sensormanager.sensor_delay_normal); } @override protected void onpause() { super.onpause(); // release camera on pause event releasecamera(); // removing inserted view - when come app // won't have views on top of each other. framelayout preview = (framelayout) findviewbyid(r.id.camera_preview); preview.removeviewat(0); }
and here camerapreview.class
public class camerapreview extends surfaceview implements surfaceholder.callback { private surfaceholder mholder; private camera mcamera; boolean ispreviewrunning = true; public camerapreview(context context, camera camera) { super(context); mcamera = camera; // install surfaceholder.callback notified when // underlying surface created , destroyed. mholder = getholder(); mholder.addcallback(this); // deprecated setting, required on android versions prior 3.0 mholder.settype(surfaceholder.surface_type_push_buffers); mholder.setfixedsize(100, 100); } public void surfacecreated(surfaceholder holder) { // surface has been created, tell camera draw // preview. try { mcamera.setpreviewdisplay(holder); mcamera.setdisplayorientation(90); mcamera.startpreview(); } catch (ioexception e) { log.d("dg_debug", "error setting camera preview: " + e.getmessage()); } } public void surfacechanged(surfaceholder holder, int format, int width, int height) { if (ispreviewrunning){ return; } ispreviewrunning = true; // 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 { mcamera.stoppreview(); } catch (exception e) { // ignore: tried stop non-existent preview } // make resize, rotate or reformatting changes here // start preview new settings try { mcamera.setpreviewdisplay(mholder); mcamera.startpreview(); } catch (exception e) { log.d("dg_debug", "error starting camera preview: " + e.getmessage()); } } public void surfacedestroyed(surfaceholder holder) { // empty. take care of releasing camera preview in activity. } }
can tell missing? if possible can chat in facebook or faster resolve of problem..
update: @likewhiteonrice's solution.
here original code
here likewhiteonrice's code:
any thoughts?
i added code below camera preview class , works devices. aware, camera library in android horrible , huge pain work with.
put function in camerapreview class:
private camera.size getoptimalsize(list<camera.size> sizes, int h, int w) { final double aspect_tolerance = 0.05; double targetratio = (double) w/h; if (sizes == null) { return null; } camera.size optimalsize = null; double mindiff = double.max_value; int targetheight = h; (camera.size size : sizes) { double ratio = (double) size.width / size.height; if (math.abs(ratio - targetratio) > aspect_tolerance) continue; if (math.abs(size.height - targetheight) < mindiff) { optimalsize = size; mindiff = math.abs(size.height - targetheight); } } if (optimalsize == null) { mindiff = double.max_value; (camera.size size : sizes) { if (math.abs(size.height - targetheight) < mindiff) { optimalsize = size; mindiff = math.abs(size.height - targetheight); } } } return optimalsize; }
in surefacecreated function, add before start preview:
camera.parameters cameraparameters = mcamera.getparameters(); list<camera.size> previewsizes = cameraparameters.getsupportedpreviewsizes(); camera.size optimalpreviewsize = getoptimalsize(previewsizes, getresources().getdisplaymetrics().widthpixels, getresources().getdisplaymetrics().heightpixels); cameraparameters.setpreviewsize(optimalpreviewsize.width, optimalpreviewsize.height); mcamera.setparameters(cameraparameters);
edit: also, i'm not sure if want
mholder.setfixedsize(100, 100);
in constructor.