2013-05-13 19 views
0

我把它從這個鏈接的代碼:爲什麼在我的Galaxy Nexus相機上使用此示例很慢?

http://www.stanford.edu/class/ee368/Android/index.html 

項目:顏色直方圖 它在我的設備上實時工作表現良好直方圖。

的問題是,如果我用我的設備攝像頭regulary它的移動速度快,流暢我的意思是我在周圍移動我的設備沒有錄像或拍照和它的移動流暢的快。

但是,一旦我使用這個項目,並實時顯示它的更慢的直方圖。

問題是爲什麼?如果有什麼辦法可以使它更平滑更快速?

這是主代碼:

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 the window title. 
     getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 
     requestWindowFeature(Window.FEATURE_NO_TITLE); 

     // Create our Preview view and set it as the 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]; 
     for (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 from YUV to 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; 
      for (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; 
      for (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; 
      for (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; 
      for (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; 
      for (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; 

     for (int j = 0, yp = 0; j < height; j++) { 
      int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; 
      for (int i = 0; i < 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; 

     for (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) 
    { 
     for (int bin = 0; bin < 256; bin++) 
     { 
      histogram[bin] = 0; 
     } // bin 
     if (component == 0) // red 
     { 
      for (int pix = 0; pix < width*height; pix += 3) 
      { 
       int pixVal = (rgb[pix] >> 16) & 0xff; 
       histogram[ pixVal ]++; 
      } // pix 
     } 
     else if (component == 1) // green 
     { 
      for (int pix = 0; pix < width*height; pix += 3) 
      { 
       int pixVal = (rgb[pix] >> 8) & 0xff; 
       histogram[ pixVal ]++; 
      } // pix 
     } 
     else // blue 
     { 
      for (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 a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and 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 is available 
      mCamera.setPreviewCallback(new PreviewCallback() { 
       public void onPreviewFrame(byte[] data, Camera camera) 
       { 
        if ((mDrawOnTop == null) || mFinished) 
         return; 

        if (mDrawOnTop.mBitmap == null) 
        { 
         // Initialize the 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 to 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 will be destroyed when we return, so stop the preview. 
     // Because the CameraDevice object is not a shared resource, it's very 
     // important to release it when the activity is paused. 
     mFinished = true; 
     mCamera.setPreviewCallback(null); 
     mCamera.stopPreview(); 
     mCamera.release(); 
     mCamera = null; 
    } 

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     // Now that the size is known, set up the camera parameters and begin 
     // the 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(); 
    } 

回答

0

很多直接在屏幕上繪圖的。一般來說,繪製到位圖的速度更快,然後只需將位圖傳送到onDraw中的屏幕即可。此外,您的onDraw是huge-你想,要小而快,做盡可能多的計算時間提前越好。你也想避免在onDraw中實例化對象或從它調用的任何函數 - 這需要時間。

基本上代碼的功能,但爲了提高效率不寫入。典型的從一個學校項目什麼(是的,這包括由助教/ PROFS書面大多數代碼),

相關問題