Android: how to display camera preview with callback?

前端 未结 6 1243
暖寄归人
暖寄归人 2020-12-03 00:18

What I need to do is quite simple, I want to manually display preview from camera using camera callback and I want to get at least 15fps on a real device. I don\'t even need

6条回答
  •  我在风中等你
    2020-12-03 00:25

    I think Michael's on the right track. First you can try this method to convert from RGB to Grayscale. Clearly it's doing almost the same thing as his,but a little more succinctly for what you want.

    //YUV Space to Greyscale
    static public void YUVtoGrayScale(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;
        }
    }
    

    }

    Second, don't create a ton of work for the garbage collector. Your bitmaps and arrays are going to be a fixed size. Create them once, not in onFramePreview.

    Doing that you'll end up with something that looks like this:

        public PreviewCallback callback = new PreviewCallback() {
        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
            if ( (mSelectView == null) || !inPreview )
                return;
            if (mSelectView.mBitmap == null)
            {
                //initialize SelectView bitmaps, arrays, etc
                //mSelectView.mBitmap = Bitmap.createBitmap(mSelectView.mImageWidth, mSelectView.mImageHeight, Bitmap.Config.RGB_565);
               //etc
    
            }
            //Pass Image Data to SelectView
            System.arraycopy(data, 0, mSelectView.mYUVData, 0, data.length);
            mSelectView.invalidate();
        }
    };
    

    And then the canvas where you want to put it looks like this:

    class SelectView extends View {
    Bitmap mBitmap;
    Bitmap croppedView;
    byte[] mYUVData;
    int[] mRGBData;
    int mImageHeight;
    int mImageWidth;
    
    public SelectView(Context context){
        super(context);
        mBitmap = null;
        croppedView = null;
    }
    
    @Override
    protected void onDraw(Canvas canvas){
        if (mBitmap != null)
        {
            int canvasWidth = canvas.getWidth();
            int canvasHeight = canvas.getHeight();
            // Convert from YUV to Greyscale
            YUVtoGrayScale(mRGBData, mYUVData, mImageWidth, mImageHeight);
                mBitmap.setPixels(mRGBData, 0, mImageWidth, 0, 0, mImageWidth, mImageHeight);
                Rect crop = new Rect(180, 220, 290, 400);
            Rect dst = new Rect(0, 0, canvasWidth, (int)(canvasHeight/2));
            canvas.drawBitmap(mBitmap, crop, dst, null);
        }
        super.onDraw(canvas);
    }
    

    This example shows a cropped and distorted selection of the camera preview in real time, but you get the idea. It runs at high FPS on a Nexus S in greyscale and should work for your needs as well.

提交回复
热议问题