码迷,mamicode.com
首页 > 其他好文 > 详细

毕业设计2_添加哈哈镜特效

时间:2015-04-23 01:50:07      阅读:180      评论:0      收藏:0      [点我收藏+]

标签:

走的思路是,添加一个ImageView控件。将预览的数据,在onPreviewFrame()里变换后,显示在ImageView控件中,再保存ImageView里的图片。

需要的话,再将ImageView控件覆盖在预览界面之上。

(也可以直接处理预览界面,但之前做的时候总是出现问题。就先再试试这个方向。)

技术分享
  1 package com.example.mycamerafinal;
  2 
  3 import java.io.FileNotFoundException;
  4 import java.io.IOException;
  5 import java.io.OutputStream;
  6 import java.util.Iterator;
  7 import java.util.List;
  8 
  9 
 10 import android.app.Activity;
 11 import android.content.ContentValues;
 12 import android.content.res.Configuration;
 13 import android.graphics.Bitmap;
 14 import android.graphics.Canvas;
 15 import android.graphics.ColorMatrix;
 16 import android.graphics.ColorMatrixColorFilter;
 17 import android.graphics.Matrix;
 18 import android.graphics.Paint;
 19 import android.graphics.Bitmap.Config;
 20 import android.hardware.Camera;
 21 import android.hardware.Camera.PreviewCallback;
 22 import android.net.Uri;
 23 import android.os.Bundle;
 24 import android.os.Message;
 25 import android.provider.MediaStore.Images.Media;
 26 import android.util.Log;
 27 import android.view.SurfaceHolder;
 28 import android.view.SurfaceView;
 29 import android.view.View;
 30 import android.view.View.OnClickListener;
 31 import android.widget.Button;
 32 import android.widget.ImageView;
 33 import android.widget.Toast;
 34 
 35 public class MainActivity extends Activity implements OnClickListener,
 36     SurfaceHolder.Callback, Camera.PictureCallback,Camera.PreviewCallback
 37 {
 38     SurfaceView cameraView;
 39     SurfaceHolder surfaceHolder;
 40     Camera camera;
 41     ImageView imgView;
 42     Button bt_takePicture;
 43     String TAG = "Camera";
 44     
 45     @Override  
 46     public void onCreate(Bundle savedInstanceState)
 47     {
 48         super.onCreate(savedInstanceState);
 49         setContentView(R.layout.activity_main);
 50         
 51         imgView = (ImageView) findViewById(R.id.ImageView);
 52         cameraView = (SurfaceView) findViewById(R.id.CameraView);
 53         bt_takePicture = (Button) findViewById(R.id.takePicture);
 54         bt_takePicture.setOnClickListener(this);
 55         surfaceHolder = cameraView.getHolder();
 56         surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
 57         surfaceHolder.addCallback(this);  
 58         cameraView.setFocusable(true);
 59         cameraView.setFocusableInTouchMode(true);
 60         //cameraView.setClickable(true);
 61         //cameraView.setOnClickListener(this);
 62     }
 63 
 64     public void onClick(View v)
 65     {
 66         camera.takePicture(null, null, this);
 67     }
 68     
 69     public void onPictureTaken(byte[] data, Camera camera)
 70     {
 71         Uri imageFileUri =  getContentResolver()
 72             .insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
 73 
 74         try {
 75             OutputStream imageFileOS =  getContentResolver()
 76                 .openOutputStream(imageFileUri);
 77             imageFileOS.write(data);
 78             imageFileOS.flush();
 79             imageFileOS.close();
 80         }
 81         catch (FileNotFoundException e)
 82         {
 83             Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
 84             t.show();
 85         }
 86        catch (IOException e)
 87        {
 88            Toast t = Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT);
 89            t.show();
 90        }
 91 
 92        camera.startPreview();
 93     }
 94 //    ...
 95     public static Bitmap toGrayscale(Bitmap bmpOriginal) {
 96         int width, height;
 97         height = bmpOriginal.getHeight();
 98         width = bmpOriginal.getWidth();
 99 
100         Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
101         Canvas c = new Canvas(bmpGrayscale);
102         Paint paint = new Paint();
103         ColorMatrix cm = new ColorMatrix();
104         cm.setSaturation(0);
105         ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
106         paint.setColorFilter(f);
107         c.drawBitmap(bmpOriginal, 0, 0, paint);
108         return bmpGrayscale;
109     }
110     
111     /**
112      * 解码
113      * 
114      * @param rgb
115      * @param yuv420sp
116      * @param width
117      * @param height
118      */
119     static public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) {
120         final int frameSize = width * height;
121 
122         for (int j = 0, yp = 0; j < height; j++) {
123             int uvp = frameSize + (j >> 1) * width, u = 0, v = 0;
124             for (int i = 0; i < width; i++, yp++) {
125                 int y = (0xff & ((int) yuv420sp[yp])) - 16;
126                 if (y < 0)
127                     y = 0;
128                 if ((i & 1) == 0) {
129                     v = (0xff & yuv420sp[uvp++]) - 128;
130                     u = (0xff & yuv420sp[uvp++]) - 128;
131                 }
132 
133                 int y1192 = 1192 * y;
134                 int r = (y1192 + 1634 * v);
135                 int g = (y1192 - 833 * v - 400 * u);
136                 int b = (y1192 + 2066 * u);
137 
138                 if (r < 0)
139                     r = 0;
140                 else if (r > 262143)
141                     r = 262143;
142                 if (g < 0)
143                     g = 0;
144                 else if (g > 262143)
145                     g = 262143;
146                 if (b < 0)
147                     b = 0;
148                 else if (b > 262143)
149                     b = 262143;
150 
151                 rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff);
152             }
153         }
154     }
155     
156     
157     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) 
158     {
159         Toast.makeText(this, "surfaceChanged", Toast.LENGTH_SHORT).show();
160         
161     }
162 
163     public void surfaceCreated(SurfaceHolder holder)
164     {
165         Toast.makeText(this, "surfaceCreated", Toast.LENGTH_SHORT).show();
166         camera = Camera.open();
167         try {           
168             camera.setPreviewDisplay(holder);
169             Camera.Parameters parameters = camera.getParameters();
170             if (this.getResources().getConfiguration().orientation 
171                 !=  Configuration.ORIENTATION_LANDSCAPE)
172             {
173                 parameters.set("orientation", "portrait"); 
174 
175                 // Android 2.2 及以上版本
176                 camera.setDisplayOrientation(90); 
177                 
178                 // Android 2.0 及以上版本
179                 parameters.setRotation(90);
180             }
181  
182             // 效果, 用于Android 2.0 及以上版本 
183             List<String> colorEffects = parameters.getSupportedColorEffects();
184             Iterator<String> cei = colorEffects.iterator();
185           
186             while (cei.hasNext()) {
187                 String currentEffect = cei.next();
188                 if (currentEffect.equals(Camera.Parameters.EFFECT_SOLARIZE))
189                 {
190                     parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
191                     break;
192                 }
193            }// End  效果, 用于Android 2.0 及以上版本 
194 
195             camera.setParameters(parameters);
196             camera.startPreview();
197             camera.setPreviewCallback(this);
198            
199         }
200         catch (IOException exception)
201         {
202             camera.release();
203         }
204     }
205   
206     public void surfaceDestroyed(SurfaceHolder holder)
207     {
208         camera.stopPreview();
209         camera.release();
210         Toast.makeText(this, "surfaceDestroyed", Toast.LENGTH_SHORT).show();
211     }
212 
213     @Override
214     public void onPreviewFrame(byte[] data, Camera arg1) {
215         // TODO Auto-generated method stub
216         
217         if (data != null) {
218             int imageWidth = arg1.getParameters().getPreviewSize().width;
219             int imageHeight = arg1.getParameters().getPreviewSize().height;
220             int RGBData[] = new int[imageWidth * imageHeight];
221             decodeYUV420SP(RGBData, data, imageWidth, imageHeight); // 解码
222             Bitmap bm = null;
223             try{
224                 bm = Bitmap.createBitmap(RGBData, imageWidth, imageHeight, Config.ARGB_8888);
225             }
226             catch(OutOfMemoryError e){
227                 Log.e(TAG,"OOE1");
228             }
229             bm = toGrayscale(bm);// 实时滤镜效果 这时把图片变成黑白
230             // 显示图片
231             Matrix mt = new Matrix();
232             mt.setRotate(90);
233             Bitmap bm2 = null;
234             try{
235                 bm2 = Bitmap.createBitmap(bm,0,0,imageWidth,imageHeight,mt,true);
236             }catch(OutOfMemoryError e){
237                 Log.e(TAG,"OOE2");
238             }
239             imgView.setImageBitmap(bm2);
240             Log.w(TAG,"to img");
241             //bm.recycle();bitmap内存管理
242         }
243     }
244 }  // End the Activity
MainActivity.java

原先的区别在于:

在onPreviewFrame()里,对data转换编码方式(不知为什么?)后,生成bm。对bm添加效果(暂用变成黑白),再配合Matrix旋转后,生成bm2。再把bm2显示在ImageView中。

问题:这里bitmap的内存管理可能会有问题。如果在每次onPreviewFrame()的最后加上bm2.recycle(),ImageView中就会是空白(虽然明明是setImageBitmap()之后才recycle()的?),并且退出程序后会报错。就把那句注释了。

技术分享
 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     android:orientation="vertical"
 4     android:layout_width="fill_parent"
 5     android:layout_height="fill_parent"  >
 6 
 7     <SurfaceView android:id="@+id/CameraView"
 8         android:layout_width="fill_parent"
 9         android:layout_height="0dp"
10         android:layout_weight="1"
11         >
12     </SurfaceView>
13     <ImageView 
14         android:id="@+id/ImageView"
15         android:layout_width="match_parent"
16         android:layout_height="0dp"
17         android:layout_weight="1"
18         />
19     <Button 
20         android:id="@+id/takePicture"
21         android:layout_width="match_parent"
22         android:layout_height="wrap_content"
23         android:text="takePicture"
24         />
25 </LinearLayout>
activity_main.xml

与原先的区别在于:

添加了ImageView控件。

毕业设计2_添加哈哈镜特效

标签:

原文地址:http://www.cnblogs.com/kiwi-bird/p/4449038.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!