Used by the camera filter to optimize the preview card screen caused by decoding and filters

Source: Internet
Author: User

In the past few days, I have seen Arthur boy's technology serialization and tried to make a camera with a filter effect. The effect has also come out. However, I found that the preview window card screen after the filter effect is added is very serious, so I tried to modify it myself. In the codes of Arthur and other netizens, the camera data video stream was basically decoded first, and then the Bitmap of the decoded frame was processed by the filter algorithm, this is a required stream, and it takes a lot of time for each frame to process decoding and filters. I tested that decoding takes about 300 milliseconds, filter processing takes about 600 milliseconds (frozen filter), so it takes 900 milliseconds or longer to process the two processes, we know that if it looks smooth, We need to update three frames per second, and this processing can only update one, obviously card screen.

So I tried to reduce the Bitmap size, and set it in the camera preview returned Photo size:

Camera. Parameters parameters = camera. getParameters (); parameters. setPreviewSize (display. getWidth ()/2, display. getHeight ()/2); // you can specify the preview size.


The original default is to return the preview image of the screen size. At this time, I changed the image to half the screen size, and found that the processing process was significantly faster (of course, there was a slight card screen ), at last, in the preview callback interface PreviewCallBack, the image is zoomed in to the screen size. In the rain, When I preview the image, it is only halved. At this time, the screen size is still very clear, if you want to speed up, you can continue to reduce the returned size of the preview image.

The Code is as follows:

Public class CameraActivity extends NoSearchActivity {private static final String TAG = "CameraActivity"; private SurfaceView surfaceView; private Camera camera; private boolean preview; private ImageButton take_picture; private int width, height; @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); Window window Window = getWindow (); requestWindowFeature (Window. FEATURE_NO_TITLE); // No title window. setFlags (WindowManager. layoutParams. FLAG_FULLSCREEN, WindowManager. layoutParams. FLAG_FULLSCREEN); // sets the full screen window. addFlags (WindowManager. layoutParams. FLAG_KEEP_SCREEN_ON); // highlight setContentView (R. layout. camera_view); ButtonClickingListener buttonlistener = new ButtonClickingListener (); surfaceView = (SurfaceView) this. findViewById (R. id. camera_surface); WindowManager wm = (WindowManager) getSystemService (Context. WINDOW_SERVICE); Display display = wm. getdefadisplay display (); width = display. getWidth (); height = display. getHeight (); take_picture = (ImageButton) findViewById (R. id. take_picture); // take_picture.setOnClickListener (buttonlistener); surfaceView. getHolder (). setFixedSize (width, height); // sets the resolution. * The Surface below does not maintain its own buffer, but waits for the rendering engine of the screen to push the content to the user */surfaceView. g EtHolder (). addCallback (new SurfaceCallback ();} // The button listens to private final class ButtonClickingListener implements View. OnClickListener {@ Override public void onClick (View v) {if (! Environment. getExternalStorageState (). equals (Environment. MEDIA_MOUNTED) {Toast. makeText (CameraActivity. this, R. string. sdcarderror, 1 ). show (); return;} try {switch (v. getId () {case R. id. take_picture: camera. takePicture (null, null, new TakePictureCallback (); break ;}} catch (Exception e) {Toast. makeText (CameraActivity. this, R. string. error, 1 ). show (); Log. e (TAG, e. toString () ;}}@ Override Protected void onDestroy () {// TODO Auto-generated method stub if (camera! = Null) {camera. setPreviewCallback (null); camera. stopPreview (); camera. release (); camera = null;} super. onDestroy ();} private final class SurfaceCallback implements SurfaceHolder. callback {@ Override public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {}@ Override public void surfaceCreated (SurfaceHolder holder) {if (camera = null) {camera = Camera. open (); // open the camera} els E {Toast. makeText (CameraActivity. this, "the camera is in use", 1 ). show ();} WindowManager wm = (WindowManager) getSystemService (Context. WINDOW_SERVICE); Display display = wm. getdefadisplay display (); Camera. parameters parameters = camera. getParameters (); parameters. setPreviewSize (display. getWidth ()/2, display. getHeight ()/2); // set the size of the previewed photo parameters. setPreviewFrameRate (3); // three parameters per second. setPictureFormat (PixelForm At. JPEG); // set the output format of the photo, parameters. set ("jpeg-quality", 100); // photo quality parameters. setPictureSize (display. getWidth (), display. getHeight (); // set the Photo size to camera. setParameters (parameters); camera. setPreviewCallback (new PreviewCallBack (); // use SurfaceView to display the camera image. startPreview (); // start previewing preview = true;} @ Override public void surfaceDestroyed (SurfaceHolder holder) {if (camera! = Null) {if (preview) camera. stopPreview (); camera. release () ;}}@ Override public boolean onKeyDown (int keyCode, KeyEvent event) {if (camera! = Null & event. getRepeatCount () = 0) {switch (keyCode) {case KeyEvent. KEYCODE_MENU: camera. autoFocus (null); // autoFocus break; case KeyEvent. KEYCODE_CAMERA: case KeyEvent. KEYCODE_DPAD_CENTER: camera. takePicture (null, null, new TakePictureCallback (); break; case KeyEvent. KEYCODE_BACK: new AlertDialog. builder (CameraActivity. this ). setTitle ("prompt "). setMessage ("are you sure you want to exit the camera? "). SetPositiveButton ("OK", new DialogInterface. onClickListener () {public void onClick (DialogInterface Diener, int whichButton) {Intent exit = new Intent (Intent. ACTION_MAIN); exit. addCategory (Intent. CATEGORY_HOME); exit. setFlags (Intent. FLAG_ACTIVITY_NEW_TASK); startActivity (exit); System. exit (0 );}}). setNegativeButton ("cancel", new DialogInterface. onClickListener () {public void onClick (DialogInterface Dialog, int whichButton) {// cancel the button event dialog. cancel ();}}). show (); break;} return super. onKeyDown (keyCode, event); // will not return to the home page} // preview the callback interface private final class PreviewCallBack implements Camera. previewCallback {public void onPreviewFrame (byte [] data, Camera camera) {if (data! = Null) {int imageWidth = camera. getParameters (). getPreviewSize (). width; int imageHeight = camera. getParameters (). getPreviewSize (). height; int RGBData [] = new int [imageWidth * imageHeight]; decodeYUV420SP (RGBData, data, imageWidth, imageHeight); // decode Bitmap bm = Bitmap. createBitmap (RGBData, imageWidth, imageHeight, Config. ARGB_8888); // bm = toGrayscale (bm); // real-time filter effect, which is now black/white. bm = ice (bm); // frozen effect C Anvas canvas = surfaceView. getHolder (). lockCanvas (); // you can use drawBitmap. if (bm! = Null) {bm = Bitmap. createScaledBitmap (bm, width, height, false); canvas. drawBitmap (bm, 0, 0, null);} surfaceView. getHolder (). unlockCanvasAndPost (canvas );}}}

Grayscale effect (black/white photo)

public static Bitmap toGrayscale(Bitmap bmp) {                 int height = bmp.getHeight();                 int width = bmp.getWidth();                 Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);                 Canvas c = new Canvas(bmpGrayscale);                 Paint paint = new Paint();                 ColorMatrix cm = new ColorMatrix();                 cm.setSaturation(0);                 ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);                 paint.setColorFilter(f);                 c.drawBitmap(bmp, 0, 0, paint);                 return bmpGrayscale;         }

Frozen Effect

Public static Bitmap ice (Bitmap bmp) {int width = bmp. getWidth (); int height = bmp. getHeight (); Bitmap bitmap = Bitmap. createBitmap (width, height, Bitmap. config. RGB_565); int dst [] = new int [width * height]; bmp. getPixels (dst, 0, width, 0, 0, width, height); int R, G, B, pixel; int pos, pixColor; for (int y = 0; y 

Retrieve photo callback

Private final class TakePictureCallback implements PictureCallback {@ Override public void onPictureTaken (byte [] data, Camera camera) {try {Bitmap bitmap = BitmapFactory. decodeByteArray (data, 0, data. length); bitmap = ice (bitmap); File file = new File (Environment. getExternalStorageDirectory (), System. currentTimeMillis () + ". jpg "); // save it in the root directory of the SD card, and name FileOutputStream outStream = new FileOutputStream (file) in milliseconds; bitmap. compress (CompressFormat. JPEG, 100, outStream); outStream. close (); camera. stopPreview (); camera. startPreview (); // start photography preview again} catch (Exception e) {Log. e (TAG, e. toString ());}}}

Decoding

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);                         }                 }         } }

Camera_view code:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"         android:orientation="horizontal" android:layout_width="fill_parent"         android:layout_height="fill_parent" android:background="#000000">         <SurfaceView android:id="@+id/camera_surface"                 android:layout_height="fill_parent"                 android:layout_width="fill_parent"                 android:layout_weight="2.0" />         <LinearLayout android:orientation="vertical"                 android:layout_width="50dip"                 android:layout_height="fill_parent"                 android:gravity="center_vertical">                 <ImageButton android:layout_width="48dip"                         android:layout_height="48dip"                         android:src="@android:drawable/ic_menu_camera"                         android:id="@+id/take_picture" />                 <View android:layout_width="40dip"                     android:layout_height="fill_parent"                     android:layout_weight="2.0"/>         </LinearLayout> </LinearLayout>

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.