android - Why using this sample on my Galaxy Nexus camera is slow? -
the code took link :
http://www.stanford.edu/class/ee368/android/index.html
the project: color histograms working showing histograms in real time on device .
the problem if i'm using device camera regulary it's moving fast , smooth mean i'm moving device around without recording video or taking photos , it's moving smooth fast.
but once i'm using project , show histograms in real time it's .
the question why ? , if there way make smoother , faster ?
this main code:
package com.example.viewfinderee368; import java.io.ioexception; import android.app.activity; import android.content.context; import android.graphics.bitmap; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.rect; import android.graphics.rectf; import android.hardware.camera; import android.hardware.camera.previewcallback; import android.os.bundle; import android.view.surfaceholder; import android.view.surfaceview; import android.view.view; import android.view.viewgroup.layoutparams; import android.view.window; import android.view.windowmanager; // ---------------------------------------------------------------------- public class viewfinderee368 extends activity { private preview mpreview; private drawontop mdrawontop; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); // hide window title. getwindow().setflags(windowmanager.layoutparams.flag_fullscreen, windowmanager.layoutparams.flag_fullscreen); requestwindowfeature(window.feature_no_title); // create our preview view , set content of our activity. // create our drawontop view. mdrawontop = new drawontop(this); mpreview = new preview(this, mdrawontop); setcontentview(mpreview); addcontentview(mdrawontop, new layoutparams(layoutparams.wrap_content, layoutparams.wrap_content)); } } //---------------------------------------------------------------------- class drawontop extends view { bitmap mbitmap; paint mpaintblack; paint mpaintyellow; paint mpaintred; paint mpaintgreen; paint mpaintblue; byte[] myuvdata; int[] mrgbdata; int mimagewidth, mimageheight; int[] mredhistogram; int[] mgreenhistogram; int[] mbluehistogram; double[] mbinsquared; public drawontop(context context) { super(context); mpaintblack = new paint(); mpaintblack.setstyle(paint.style.fill); mpaintblack.setcolor(color.black); mpaintblack.settextsize(25); mpaintyellow = new paint(); mpaintyellow.setstyle(paint.style.fill); mpaintyellow.setcolor(color.yellow); mpaintyellow.settextsize(25); mpaintred = new paint(); mpaintred.setstyle(paint.style.fill); mpaintred.setcolor(color.red); mpaintred.settextsize(25); mpaintgreen = new paint(); mpaintgreen.setstyle(paint.style.fill); mpaintgreen.setcolor(color.green); mpaintgreen.settextsize(25); mpaintblue = new paint(); mpaintblue.setstyle(paint.style.fill); mpaintblue.setcolor(color.blue); mpaintblue.settextsize(25); mbitmap = null; myuvdata = null; mrgbdata = null; mredhistogram = new int[256]; mgreenhistogram = new int[256]; mbluehistogram = new int[256]; mbinsquared = new double[256]; (int bin = 0; bin < 256; bin++) { mbinsquared[bin] = ((double)bin) * bin; } // bin } @override protected void ondraw(canvas canvas) { if (mbitmap != null) { int canvaswidth = canvas.getwidth(); int canvasheight = canvas.getheight(); int newimagewidth = canvaswidth; int newimageheight = canvasheight; int marginwidth = (canvaswidth - newimagewidth)/2; // convert yuv rgb decodeyuv420sp(mrgbdata, myuvdata, mimagewidth, mimageheight); // draw bitmap mbitmap.setpixels(mrgbdata, 0, mimagewidth, 0, 0, mimagewidth, mimageheight); rect src = new rect(0, 0, mimagewidth, mimageheight); rect dst = new rect(marginwidth, 0, canvaswidth-marginwidth, canvasheight); canvas.drawbitmap(mbitmap, src, dst, mpaintblack); // draw black borders canvas.drawrect(0, 0, marginwidth, canvasheight, mpaintblack); canvas.drawrect(canvaswidth - marginwidth, 0, canvaswidth, canvasheight, mpaintblack); // calculate histogram calculateintensityhistogram(mrgbdata, mredhistogram, mimagewidth, mimageheight, 0); calculateintensityhistogram(mrgbdata, mgreenhistogram, mimagewidth, mimageheight, 1); calculateintensityhistogram(mrgbdata, mbluehistogram, mimagewidth, mimageheight, 2); // calculate mean double imageredmean = 0, imagegreenmean = 0, imagebluemean = 0; double redhistogramsum = 0, greenhistogramsum = 0, bluehistogramsum = 0; (int bin = 0; bin < 256; bin++) { imageredmean += mredhistogram[bin] * bin; redhistogramsum += mredhistogram[bin]; imagegreenmean += mgreenhistogram[bin] * bin; greenhistogramsum += mgreenhistogram[bin]; imagebluemean += mbluehistogram[bin] * bin; bluehistogramsum += mbluehistogram[bin]; } // bin imageredmean /= redhistogramsum; imagegreenmean /= greenhistogramsum; imagebluemean /= bluehistogramsum; // calculate second moment double imagered2ndmoment = 0, imagegreen2ndmoment = 0, imageblue2ndmoment = 0; (int bin = 0; bin < 256; bin++) { imagered2ndmoment += mredhistogram[bin] * mbinsquared[bin]; imagegreen2ndmoment += mgreenhistogram[bin] * mbinsquared[bin]; imageblue2ndmoment += mbluehistogram[bin] * mbinsquared[bin]; } // bin imagered2ndmoment /= redhistogramsum; imagegreen2ndmoment /= greenhistogramsum; imageblue2ndmoment /= bluehistogramsum; double imageredstddev = math.sqrt( imagered2ndmoment - imageredmean*imageredmean ); double imagegreenstddev = math.sqrt( imagegreen2ndmoment - imagegreenmean*imagegreenmean ); double imagebluestddev = math.sqrt( imageblue2ndmoment - imagebluemean*imagebluemean ); // draw mean string imagemeanstr = "mean (r,g,b): " + string.format("%.4g", imageredmean) + ", " + string.format("%.4g", imagegreenmean) + ", " + string.format("%.4g", imagebluemean); canvas.drawtext(imagemeanstr, marginwidth+10-1, 30-1, mpaintblack); canvas.drawtext(imagemeanstr, marginwidth+10+1, 30-1, mpaintblack); canvas.drawtext(imagemeanstr, marginwidth+10+1, 30+1, mpaintblack); canvas.drawtext(imagemeanstr, marginwidth+10-1, 30+1, mpaintblack); canvas.drawtext(imagemeanstr, marginwidth+10, 30, mpaintyellow); // draw standard deviation string imagestddevstr = "std dev (r,g,b): " + string.format("%.4g", imageredstddev) + ", " + string.format("%.4g", imagegreenstddev) + ", " + string.format("%.4g", imagebluestddev); canvas.drawtext(imagestddevstr, marginwidth+10-1, 60-1, mpaintblack); canvas.drawtext(imagestddevstr, marginwidth+10+1, 60-1, mpaintblack); canvas.drawtext(imagestddevstr, marginwidth+10+1, 60+1, mpaintblack); canvas.drawtext(imagestddevstr, marginwidth+10-1, 60+1, mpaintblack); canvas.drawtext(imagestddevstr, marginwidth+10, 60, mpaintyellow); // draw red intensity histogram float barmaxheight = 3000; float barwidth = ((float)newimagewidth) / 256; float barmarginheight = 2; rectf barrect = new rectf(); barrect.bottom = canvasheight - 200; barrect.left = marginwidth; barrect.right = barrect.left + barwidth; (int bin = 0; bin < 256; bin++) { float prob = (float)mredhistogram[bin] / (float)redhistogramsum; barrect.top = barrect.bottom - math.min(80,prob*barmaxheight) - barmarginheight; canvas.drawrect(barrect, mpaintblack); barrect.top += barmarginheight; canvas.drawrect(barrect, mpaintred); barrect.left += barwidth; barrect.right += barwidth; } // bin // draw green intensity histogram barrect.bottom = canvasheight - 100; barrect.left = marginwidth; barrect.right = barrect.left + barwidth; (int bin = 0; bin < 256; bin++) { barrect.top = barrect.bottom - math.min(80, ((float)mgreenhistogram[bin])/((float)greenhistogramsum) * barmaxheight) - barmarginheight; canvas.drawrect(barrect, mpaintblack); barrect.top += barmarginheight; canvas.drawrect(barrect, mpaintgreen); barrect.left += barwidth; barrect.right += barwidth; } // bin // draw blue intensity histogram barrect.bottom = canvasheight; barrect.left = marginwidth; barrect.right = barrect.left + barwidth; (int bin = 0; bin < 256; bin++) { barrect.top = barrect.bottom - math.min(80, ((float)mbluehistogram[bin])/((float)bluehistogramsum) * barmaxheight) - barmarginheight; canvas.drawrect(barrect, mpaintblack); barrect.top += barmarginheight; canvas.drawrect(barrect, mpaintblue); barrect.left += barwidth; barrect.right += barwidth; } // bin } // end if statement super.ondraw(canvas); } // end ondraw method static public void decodeyuv420sp(int[] rgb, byte[] yuv420sp, int width, int height) { final int framesize = width * height; (int j = 0, yp = 0; j < height; j++) { int uvp = framesize + (j >> 1) * width, u = 0, v = 0; (int = 0; < width; i++, yp++) { int y = (0xff & ((int) yuv420sp[yp])) - 16; if (y < 0) y = 0; if ((i & 1) == 0) { v = (0xff & yuv420sp[uvp++]) - 128; u = (0xff & yuv420sp[uvp++]) - 128; } int y1192 = 1192 * y; int r = (y1192 + 1634 * v); int g = (y1192 - 833 * v - 400 * u); int b = (y1192 + 2066 * u); if (r < 0) r = 0; else if (r > 262143) r = 262143; if (g < 0) g = 0; else if (g > 262143) g = 262143; if (b < 0) b = 0; else if (b > 262143) b = 262143; rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); } } } static public void decodeyuv420spgrayscale(int[] rgb, byte[] yuv420sp, int width, int height) { final int framesize = width * height; (int pix = 0; pix < framesize; pix++) { int pixval = (0xff & ((int) yuv420sp[pix])) - 16; if (pixval < 0) pixval = 0; if (pixval > 255) pixval = 255; rgb[pix] = 0xff000000 | (pixval << 16) | (pixval << 8) | pixval; } // pix } static public void calculateintensityhistogram(int[] rgb, int[] histogram, int width, int height, int component) { (int bin = 0; bin < 256; bin++) { histogram[bin] = 0; } // bin if (component == 0) // red { (int pix = 0; pix < width*height; pix += 3) { int pixval = (rgb[pix] >> 16) & 0xff; histogram[ pixval ]++; } // pix } else if (component == 1) // green { (int pix = 0; pix < width*height; pix += 3) { int pixval = (rgb[pix] >> 8) & 0xff; histogram[ pixval ]++; } // pix } else // blue { (int pix = 0; pix < width*height; pix += 3) { int pixval = rgb[pix] & 0xff; histogram[ pixval ]++; } // pix } } } // ---------------------------------------------------------------------- class preview extends surfaceview implements surfaceholder.callback { surfaceholder mholder; camera mcamera; drawontop mdrawontop; boolean mfinished; preview(context context, drawontop drawontop) { super(context); mdrawontop = drawontop; mfinished = false; // install surfaceholder.callback notified when // underlying surface created , destroyed. mholder = getholder(); mholder.addcallback(this); mholder.settype(surfaceholder.surface_type_push_buffers); } public void surfacecreated(surfaceholder holder) { mcamera = camera.open(); try { mcamera.setpreviewdisplay(holder); // preview callback used whenever new viewfinder frame available mcamera.setpreviewcallback(new previewcallback() { public void onpreviewframe(byte[] data, camera camera) { if ( (mdrawontop == null) || mfinished ) return; if (mdrawontop.mbitmap == null) { // initialize draw-on-top companion camera.parameters params = camera.getparameters(); mdrawontop.mimagewidth = params.getpreviewsize().width; mdrawontop.mimageheight = params.getpreviewsize().height; mdrawontop.mbitmap = bitmap.createbitmap(mdrawontop.mimagewidth, mdrawontop.mimageheight, bitmap.config.rgb_565); mdrawontop.mrgbdata = new int[mdrawontop.mimagewidth * mdrawontop.mimageheight]; mdrawontop.myuvdata = new byte[data.length]; } // pass yuv data draw-on-top companion system.arraycopy(data, 0, mdrawontop.myuvdata, 0, data.length); mdrawontop.invalidate(); } }); } catch (ioexception exception) { mcamera.release(); mcamera = null; } } public void surfacedestroyed(surfaceholder holder) { // surface destroyed when return, stop preview. // because cameradevice object not shared resource, it's // important release when activity paused. mfinished = true; mcamera.setpreviewcallback(null); mcamera.stoppreview(); mcamera.release(); mcamera = null; } public void surfacechanged(surfaceholder holder, int format, int w, int h) { // size known, set camera parameters , begin // preview. camera.parameters parameters = mcamera.getparameters(); parameters.setpreviewsize(320, 240); parameters.setpreviewframerate(15); parameters.setscenemode(camera.parameters.scene_mode_night); parameters.setfocusmode(camera.parameters.focus_mode_auto); mcamera.setparameters(parameters); mcamera.startpreview(); }
lots of direct drawing screen. faster draw bitmap, transfer bitmap screen in ondraw. also, ondraw huge- want small , fast, doing of calculations ahead of time possible. want avoid instantiating objects in ondraw or functions called it- takes time.
basically code functional not written efficiency. typical of school project (yes, includes code written tas/profs),
Comments
Post a Comment