Commit ad7707c8 by maiqh

修复卡顿问题,去掉冗余代码

parent ae328dd2
......@@ -33,10 +33,6 @@
</intent-filter>
</activity>
<activity android:name=".Camera2Activity"/>
<!-- <activity android:name=".mtk.MTKCameraActivity"/>-->
<activity android:name=".video.CameraActivity"/>
<activity android:name=".getpreview.PreviewActivity"/>
<activity android:name=".camera1.Camera1"/>
<service android:name="com.autonavi.amapauto.gdarcameraservicedemo.GDArCameraService"
android:exported="true">
......@@ -45,7 +41,7 @@
</intent-filter>
</service>
<receiver android:name="com.autonavi.amapauto.ArCameraIdBroadcast" android:exported="true">
<receiver android:name="com.autonavi.amapauto.gdarcameraservicedemo.ArCameraIdBroadcast" android:exported="true">
<intent-filter>
<action android:name="AUTONAVI_STANDARD_BROADCAST_SEND"/>
</intent-filter>
......
package com.autonavi.amapauto.camera1;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import java.io.IOException;
public class Camera1Helper {
private final static String TAG = "Camera1Helper";
private Camera mCamera;
public Camera open(){
mCamera = null;
try {
mCamera = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return mCamera; // returns null if camera is unavailable
}
public void setHolder(SurfaceHolder mHolder) {
mHolder.addCallback(callback);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
SurfaceHolder.Callback callback= new SurfaceHolder.Callback(){
@Override
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG, "onPreviewFrame : " + data);
}
});
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// If your preview can change or rotate, take care of those events here.
// Make sure to stop the preview before resizing or reformatting it.
if (holder.getSurface() == null) {
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e) {
// ignore: tried to stop a non-existent preview
}
// set preview size and make any resize, rotate or
// reformatting changes here
// start preview with new settings
try {
mCamera.setPreviewDisplay(holder);
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG, "onPreviewFrame : " + data);
}
});
mCamera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
};
}
package com.autonavi.amapauto.gdarcameraservicedemo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import com.autonavi.amapauto.gdarcameraservicedemo.utils.BroadcastUtils;
public class ArCameraIdBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("AUTONAVI_STANDARD_BROADCAST_SEND".equals(action)) {
int key_type = intent.getIntExtra("KEY_TYPE", -1);
if (key_type == 12116) {
// 高德那边说:不一定是收到我们的请求你们才发,我们会去请求,另外,你们如果自己摄像头链接有变化时也要主动发送这条广播给我们
BroadcastUtils.sendCameraConfigBroadcast(context);
}
}
}
}
......@@ -155,7 +155,6 @@ public class GDArCameraService extends Service {
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG, "onPreviewFrame: " + data.toString());
try {
sendData(data, camera);
} catch (IOException e) {
......@@ -223,7 +222,6 @@ public class GDArCameraService extends Service {
try {
SharedMemUtils.setCanRead(buffer);
mMemoryFile.writeBytes(buffer, 0, 0, buffer.length);
Log.d(TAG, "CNEEDS_TEST sendData: " + Arrays.toString(buffer));
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "sendDataError: " + e.getMessage());
......
package com.autonavi.amapauto;
package com.autonavi.amapauto.gdarcameraservicedemo.utils;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class ArCameraIdBroadcast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if ("AUTONAVI_STANDARD_BROADCAST_SEND".equals(action)) {
int key_type = intent.getIntExtra("KEY_TYPE", -1);
if (key_type == 12116) {
// 不一定是收到我们的请求你们才发,我们会去请求,另外,你们如果自己摄像头链接有变化时也要主动发送这条广播给我们
Intent receiverIntent = new Intent();
receiverIntent.setAction("AUTONAVI_STANDARD_BROADCAST_RECV");
receiverIntent.putExtra("KEY_TYPE", 12116);
receiverIntent.putExtra("productName", "智能网联车盒");
receiverIntent.putExtra("productModel", "M2");
receiverIntent.putExtra("cameraDisplay", "1280x720");
receiverIntent.putExtra("cameraName", "C2390");
receiverIntent.putExtra("imu", "MPU-6050");
receiverIntent.putExtra("cameraConnect", "MIPI");
context.sendBroadcast(receiverIntent);
}
}
public class BroadcastUtils {
public static void sendCameraConfigBroadcast(Context context) {
Intent receiverIntent = new Intent();
receiverIntent.setAction("AUTONAVI_STANDARD_BROADCAST_RECV");
receiverIntent.putExtra("KEY_TYPE", 12116);
receiverIntent.putExtra("productName", "智能网联车盒");
receiverIntent.putExtra("productModel", "M2");
receiverIntent.putExtra("cameraDisplay", "1280x720");
receiverIntent.putExtra("cameraName", "C2390");
receiverIntent.putExtra("imu", "MPU-6050");
receiverIntent.putExtra("cameraConnect", "MIPI");
context.sendBroadcast(receiverIntent);
}
}
package com.example.cameraservicedemo;
import android.app.Activity;
import android.os.Bundle;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
public class Camera2Activity extends Activity {
private TextureView mTextureView;
private Button mBtnOpenCamera;
private Button mBtnCloseCamera;
private Camera2Helper mCamera2Helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera2);
mTextureView = (TextureView) findViewById(R.id.texture_view);
mBtnOpenCamera = (Button) findViewById(R.id.btn_open_camera);
mBtnCloseCamera = (Button) findViewById(R.id.btn_close_camera);
mCamera2Helper = new Camera2Helper(Camera2Activity.this, mTextureView);
mBtnOpenCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera2Helper.initCameraInfo();
}
});
mBtnCloseCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mCamera2Helper.releaseCamera();
mCamera2Helper.releaseThread();
}
});
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
mCamera2Helper.releaseCamera();
mCamera2Helper.releaseThread();
}
}
\ No newline at end of file
......@@ -3,74 +3,28 @@ package com.example.cameraservicedemo;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import com.example.cameraservicedemo.camera1.Camera1;
import com.example.cameraservicedemo.getpreview.PreviewActivity;
import com.example.cameraservicedemo.video.CameraActivity;
public class MainActivity extends Activity implements View.OnClickListener {
private Button mBtnCamera2;
private Button mBtnVideo;
private Button mBtnMTKCamera;
private Button btn_preview;
private Button btn_camera1;
private Camera2Helper mCamera2Helper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBtnCamera2 = (Button) findViewById(R.id.btn_camera2);
mBtnVideo = (Button) findViewById(R.id.btn_video);
mBtnMTKCamera = (Button) findViewById(R.id.btn_mtk_camera);
btn_preview = (Button) findViewById(R.id.btn_preview);
btn_camera1 = (Button) findViewById(R.id.btn_camera1);
mBtnCamera2.setOnClickListener(this);
mBtnMTKCamera.setOnClickListener(this);
mBtnVideo.setOnClickListener(this);
btn_preview.setOnClickListener(this);
btn_camera1.setOnClickListener(this);
}
@Override
protected void onResume() {
super.onResume();
}
@Override
protected void onPause() {
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
@Override
public void onClick(View v) {
Intent intent;
switch (v.getId()) {
case R.id.btn_camera2:
intent = new Intent(MainActivity.this, Camera2Activity.class);
startActivity(intent);
break;
case R.id.btn_mtk_camera:
// intent = new Intent(MainActivity.this, MTKCameraActivity.class);
// startActivity(intent);
break;
case R.id.btn_video:
intent = new Intent(MainActivity.this, CameraActivity.class);
startActivity(intent);
break;
case R.id.btn_preview:
intent = new Intent(MainActivity.this, PreviewActivity.class);
startActivity(intent);
break;
case R.id.btn_camera1:
intent = new Intent(MainActivity.this, Camera1.class);
startActivity(intent);
......
package com.example.cameraservicedemo.getpreview;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;
import com.example.cameraservicedemo.getpreview.util.Camera2Proxy;
public class Camera2View extends TextureView {
private static final String TAG = "Camera2View";
private Camera2Proxy mCameraProxy;
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public Camera2View(Context context) {
this(context, null);
}
public Camera2View(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public Camera2View(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs, defStyleAttr, 0);
}
public Camera2View(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
mCameraProxy = new Camera2Proxy((Activity) context);
}
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
requestLayout();
}
public Camera2Proxy getCameraProxy() {
return mCameraProxy;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
} else {
setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
}
}
}
}
package com.example.cameraservicedemo.getpreview;
import android.app.Fragment;
import android.graphics.SurfaceTexture;
import android.media.Image;
import android.media.ImageReader;
import android.os.Bundle;
import android.util.Size;
import android.view.LayoutInflater;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import com.example.cameraservicedemo.R;
import com.example.cameraservicedemo.getpreview.util.Camera2Proxy;
import java.nio.ByteBuffer;
public class CameraFragment extends Fragment implements View.OnClickListener {
private static final String TAG = "CameraFragment";
private ImageView mCloseIv;
private ImageView mSwitchCameraIv;
private ImageView mTakePictureIv;
private Camera2View mCameraView;
private Camera2Proxy mCameraProxy;
private final TextureView.SurfaceTextureListener mSurfaceTextureListener
= new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
mCameraProxy.openCamera();
mCameraProxy.setPreviewSurface(texture);
// 根据相机预览设置View大小,避免显示变形
Size previewSize = mCameraProxy.getPreviewSize();
mCameraView.setAspectRatio(previewSize.getHeight(), previewSize.getWidth());
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
}
};
@Override
public View onCreateView( LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_camera, null);
initView(rootView);
return rootView;
}
private void initView(View rootView) {
mCloseIv = (ImageView) rootView.findViewById(R.id.toolbar_close_iv);
mSwitchCameraIv = (ImageView) rootView.findViewById(R.id.toolbar_switch_iv);
mTakePictureIv = (ImageView) rootView.findViewById(R.id.take_picture_iv);
mCameraView = (Camera2View) rootView.findViewById(R.id.camera_view);
mCameraProxy = mCameraView.getCameraProxy();
mCloseIv.setOnClickListener(this);
mSwitchCameraIv.setOnClickListener(this);
mTakePictureIv.setOnClickListener(this);
mCameraProxy.setImageAvailableListener(mOnImageAvailableListener);
}
@Override
public void onResume() {
super.onResume();
if (mCameraView.isAvailable()) {
mCameraProxy.openCamera();
} else {
mCameraView.setSurfaceTextureListener(mSurfaceTextureListener);
}
}
@Override
public void onPause() {
super.onPause();
mCameraProxy.releaseCamera();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.toolbar_close_iv:
getActivity().finish();
break;
case R.id.toolbar_switch_iv:
mCameraProxy.switchCamera();
break;
case R.id.take_picture_iv:
mIsShutter = true;
break;
}
}
private byte[] mYuvBytes;
private boolean mIsShutter;
private ImageReader.OnImageAvailableListener mOnImageAvailableListener
= new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = reader.acquireLatestImage();
if (image == null) {
return;
}
int width = mCameraProxy.getPreviewSize().getWidth();
int height = mCameraProxy.getPreviewSize().getHeight();
if (mYuvBytes == null) {
// YUV420 大小总是 width * height * 3 / 2
mYuvBytes = new byte[width * height * 3 / 2];
}
// YUV_420_888
Image.Plane[] planes = image.getPlanes();
// Y通道,对应planes[0]
// Y size = width * height
// yBuffer.remaining() = width * height;
// pixelStride = 1
ByteBuffer yBuffer = planes[0].getBuffer();
int yLen = width * height;
yBuffer.get(mYuvBytes, 0, yLen);
// U通道,对应planes[1]
// U size = width * height / 4;
// uBuffer.remaining() = width * height / 2;
// pixelStride = 2
ByteBuffer uBuffer = planes[1].getBuffer();
int pixelStride = planes[1].getPixelStride(); // pixelStride = 2
for (int i = 0; i < uBuffer.remaining(); i+=pixelStride) {
mYuvBytes[yLen++] = uBuffer.get(i);
}
// V通道,对应planes[2]
// V size = width * height / 4;
// vBuffer.remaining() = width * height / 2;
// pixelStride = 2
ByteBuffer vBuffer = planes[2].getBuffer();
pixelStride = planes[2].getPixelStride(); // pixelStride = 2
for (int i = 0; i < vBuffer.remaining(); i+=pixelStride) {
mYuvBytes[yLen++] = vBuffer.get(i);
}
if (mIsShutter) {
mIsShutter = false;
// save yuv data
// String yuvPath = FileUtil.SAVE_DIR + System.currentTimeMillis() + ".yuv";
// FileUtil.saveBytes(mYuvBytes, yuvPath);
// save bitmap data
// String jpgPath = yuvPath.replace(".yuv", ".jpg");
// Bitmap bitmap = ColorConvertUtil.yuv420pToBitmap(mYuvBytes, width, height);
// FileUtil.saveBitmap(bitmap, jpgPath);
}
// 一定不能忘记close
image.close();
}
};
}
package com.example.cameraservicedemo.getpreview;
import android.app.Activity;
import android.os.Bundle;
import com.example.cameraservicedemo.R;
import com.example.cameraservicedemo.video.Camera2VideoFragment;
public class PreviewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
if (null == savedInstanceState) {
}
}
@Override
protected void onResume() {
super.onResume();
getFragmentManager().beginTransaction()
.replace(R.id.container, new CameraFragment())
.commit();
}
}
package com.example.cameraservicedemo.getpreview.util;
import android.app.Activity;
import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import java.util.Arrays;
public class Camera2Proxy {
private static final String TAG = "Camera2Proxy";
private Activity mActivity;
// camera
private int mCameraId = CameraCharacteristics.LENS_FACING_FRONT; // 要打开的摄像头ID
private Size mPreviewSize = new Size(640, 480); // 固定640*480演示
private CameraDevice mCameraDevice; // 相机对象
private CameraCaptureSession mCaptureSession;
// handler
private Handler mBackgroundHandler;
private HandlerThread mBackgroundThread;
// output
private Surface mPreviewSurface; // 输出到屏幕的预览
private ImageReader mImageReader; // 预览回调的接收者
private ImageReader.OnImageAvailableListener mOnImageAvailableListener;
/**
* 打开摄像头的回调
*/
private CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened( CameraDevice camera) {
Log.d(TAG, "onOpened");
mCameraDevice = camera;
initPreviewRequest();
}
@Override
public void onDisconnected( CameraDevice camera) {
Log.d(TAG, "onDisconnected");
releaseCamera();
}
@Override
public void onError( CameraDevice camera, int error) {
Log.e(TAG, "Camera Open failed, error: " + error);
releaseCamera();
}
};
public Camera2Proxy(Activity activity) {
mActivity = activity;
}
public void openCamera() {
Log.v(TAG, "openCamera");
startBackgroundThread(); // 对应 releaseCamera() 方法中的 stopBackgroundThread()
try {
CameraManager cameraManager = (CameraManager) mActivity.getSystemService(Context.CAMERA_SERVICE);
Log.d(TAG, "preview size: " + mPreviewSize.getWidth() + "*" + mPreviewSize.getHeight());
mImageReader = ImageReader.newInstance(mPreviewSize.getWidth(), mPreviewSize.getHeight(),
ImageFormat.YUV_420_888, 2);
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, null);
// 打开摄像头
cameraManager.openCamera(Integer.toString(mCameraId), mStateCallback, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
public void releaseCamera() {
Log.v(TAG, "releaseCamera");
if (mImageReader != null) {
mImageReader.close();
mImageReader = null;
}
if (mCaptureSession != null) {
mCaptureSession.close();
mCaptureSession = null;
}
if (mCameraDevice != null) {
mCameraDevice.close();
mCameraDevice = null;
}
stopBackgroundThread(); // 对应 openCamera() 方法中的 startBackgroundThread()
}
public void setImageAvailableListener(ImageReader.OnImageAvailableListener onImageAvailableListener) {
mOnImageAvailableListener = onImageAvailableListener;
}
public void setPreviewSurface(SurfaceTexture surfaceTexture) {
// mPreviewSize必须先初始化完成
surfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
mPreviewSurface = new Surface(surfaceTexture);
}
private void initPreviewRequest() {
try {
final CaptureRequest.Builder builder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 添加输出到屏幕的surface
builder.addTarget(mPreviewSurface);
// 添加输出到ImageReader的surface。然后我们就可以从ImageReader中获取预览数据了
builder.addTarget(mImageReader.getSurface());
mCameraDevice.createCaptureSession(Arrays.asList(mPreviewSurface, mImageReader.getSurface()),
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured( CameraCaptureSession session) {
mCaptureSession = session;
// 设置连续自动对焦和自动曝光
builder.set(CaptureRequest.CONTROL_AF_MODE,
CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
builder.set(CaptureRequest.CONTROL_AE_MODE,
CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
CaptureRequest captureRequest = builder.build();
try {
// 一直发送预览请求
mCaptureSession.setRepeatingRequest(captureRequest, null, mBackgroundHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed( CameraCaptureSession session) {
Log.e(TAG, "ConfigureFailed. session: mCaptureSession");
}
}, mBackgroundHandler); // handle 传入 null 表示使用当前线程的 Looper
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
public Size getPreviewSize() {
return mPreviewSize;
}
public void switchCamera() {
mCameraId ^= 1;
Log.d(TAG, "switchCamera: mCameraId: " + mCameraId);
releaseCamera();
openCamera();
}
private void startBackgroundThread() {
if (mBackgroundThread == null || mBackgroundHandler == null) {
Log.v(TAG, "startBackgroundThread");
mBackgroundThread = new HandlerThread("CameraBackground");
mBackgroundThread.start();
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
}
}
private void stopBackgroundThread() {
Log.v(TAG, "stopBackgroundThread");
mBackgroundThread.quitSafely();
try {
mBackgroundThread.join();
mBackgroundThread = null;
mBackgroundHandler = null;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.example.cameraservicedemo.getpreview.util;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.util.Log;
import java.nio.ByteBuffer;
public class ColorConvertUtil {
private static final String TAG = "ColorConvertUtil";
public static Bitmap yuv420pToBitmap(byte[] yuv420p, int width, int height) {
if (yuv420p == null || width < 0 || height < 0) {
Log.e(TAG, "cropNv21ToBitmap failed: illegal para !");
return null;
}
byte[] rgba = new byte[width * height * 4];
ColorConvertUtil.yuv420pToRGBA(yuv420p, width, height, rgba);
Bitmap bitmap = byteArrayToBitmap(rgba, width, height);
return bitmap;
}
public static void yuv420pToRGBA(byte[] yuv420p, int width, int height, byte[] rgba) {
if (yuv420p == null || rgba == null) {
Log.e(TAG, "yuv420pToRGBA failed: yuv420p or rgba is null ");
return;
}
if (yuv420p.length != width * height * 3 / 2) {
Log.e(TAG, "yuv420p length: " + yuv420p.length);
Log.e(TAG, "yuv420pToRGBA failed: yuv420p length error!");
return;
}
// NativeLibrary.yuv420p2rgba(yuv420p, width, height, rgba);
}
/**
* 将 rgba 的 byte[] 数据转换成 bitmap
*
* @param rgba 输入的 rgba 数据
* @param width 图片宽度
* @param height 图片高度
* @return 得到的 bitmap
*/
public static Bitmap byteArrayToBitmap(byte[] rgba, int width, int height) {
ByteBuffer buffer = ByteBuffer.wrap(rgba);
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
return bitmap;
}
public static Bitmap rotateBitmap(Bitmap bitmap, int rotate, boolean mirrorX) {
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
if (mirrorX) {
matrix.postScale(-1f, 1f);
}
Bitmap rotateBitmap = null;
if (bitmap != null) {
rotateBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
bitmap.recycle(); // 回收旧Bitmap
}
return rotateBitmap;
}
}
package com.example.cameraservicedemo.getpreview.util;
import android.graphics.Bitmap;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileUtil {
public static final String SAVE_DIR = "/sdcard/DCIM/Camera2GetPreview/";
public static boolean saveBytes(byte[] bytes, String imagePath) {
File file = new File(imagePath);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
try {
FileOutputStream fos = new FileOutputStream(file);
fos.write(bytes);
fos.flush();
fos.close();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
public static boolean saveBitmap(Bitmap bitmap, String imagePath) {
if (bitmap == null) {
return false;
}
File file = new File(imagePath);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
try {
FileOutputStream fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
return true;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
}
package com.example.cameraservicedemo.getpreview.util;
public class NativeLibrary {
// static {
// System.loadLibrary("native-lib");
// }
// public static native void yuv420p2rgba(byte[] yuv420p,
// int width,
// int height,
// byte[] rgba);
}
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.cameraservicedemo.video;
import android.content.Context;
import android.util.AttributeSet;
import android.view.TextureView;
/**
* A {@link TextureView} that can be adjusted to a specified aspect ratio.
*/
public class AutoFitTextureView extends TextureView {
private int mRatioWidth = 0;
private int mRatioHeight = 0;
public AutoFitTextureView(Context context) {
this(context, null);
}
public AutoFitTextureView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
*
* @param width Relative horizontal size
* @param height Relative vertical size
*/
public void setAspectRatio(int width, int height) {
if (width < 0 || height < 0) {
throw new IllegalArgumentException("Size cannot be negative.");
}
mRatioWidth = width;
mRatioHeight = height;
requestLayout();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = MeasureSpec.getSize(heightMeasureSpec);
if (0 == mRatioWidth || 0 == mRatioHeight) {
setMeasuredDimension(width, height);
} else {
if (width < height * mRatioWidth / mRatioHeight) {
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
} else {
setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
}
}
}
}
/*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.cameraservicedemo.video;
import android.app.Activity;
import android.os.Bundle;
import com.example.cameraservicedemo.R;
public class CameraActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
if (null == savedInstanceState) {
getFragmentManager().beginTransaction()
.replace(R.id.container, Camera2VideoFragment.newInstance())
.commit();
}
}
}
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000" />
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextureView
android:id="@+id/texture_view"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_open_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="打开摄像头"/>
<Button
android:id="@+id/btn_close_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="关闭摄像头"/>
</LinearLayout>
</FrameLayout>
\ No newline at end of file
......@@ -3,14 +3,6 @@
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="@+id/btn_camera2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="Camera2"
/>
<Button
android:id="@+id/btn_camera1"
android:layout_width="wrap_content"
......@@ -18,26 +10,4 @@
android:padding="20dp"
android:text="camera1"
/>
<Button
android:id="@+id/btn_preview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="btn_preview"
/>
<Button
android:id="@+id/btn_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="video"
/>
<Button
android:id="@+id/btn_mtk_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="20dp"
android:text="MTK Camera"
/>
</LinearLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="@+id/big_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<SurfaceView
android:id="@+id/sv_mkt"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_open_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="打开摄像头"/>
<Button
android:id="@+id/btn_close_camera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="10dp"
android:text="关闭摄像头"/>
</LinearLayout>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorPrimary">
<!-- <android.support.v7.widget.Toolbar-->
<!-- android:id="@+id/toolbar"-->
<!-- android:layout_width="match_parent"-->
<!-- android:layout_height="?android:actionBarSize"-->
<!-- android:background="@color/colorPrimary"-->
<!-- app:contentInsetStart="0dp">-->
<LinearLayout
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:id="@+id/toolbar_close_iv"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_vertical"
android:padding="10dp"
android:src="@mipmap/ic_close"/>
<Space
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="1"/>
<ImageView
android:id="@+id/toolbar_switch_iv"
android:layout_width="45dp"
android:layout_height="45dp"
android:layout_gravity="center_vertical"
android:padding="10dp"
android:src="@mipmap/ic_camera_switch"/>
</LinearLayout>
<!-- </android.support.v7.widget.Toolbar>-->
<com.example.cameraservicedemo.getpreview.Camera2View
android:id="@+id/camera_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/toolbar">
</com.example.cameraservicedemo.getpreview.Camera2View>
<ImageView
android:id="@+id/take_picture_iv"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="20dp"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2014 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.example.cameraservicedemo.video.AutoFitTextureView
android:id="@+id/texture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true"
android:layout_below="@id/texture"
android:background="#4285f4">
<Button
android:id="@+id/video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="@string/record" />
<ImageButton
android:id="@+id/info"
android:contentDescription="@string/description_info"
style="@android:style/Widget.Material.Light.Button.Borderless"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical|right"
android:padding="20dp"
android:src="@mipmap/ic_launcher" />
</FrameLayout>
</RelativeLayout>
重要的类只有一个:
com.autonavi.amapauto.gdarcameraservicedemo.GDArCameraService.java
AIDL服务端源码在目录:
com.autonavi.amapauto.gdarcameraservicedemo
重要的类是:
com.autonavi.amapauto.gdarcameraservicedemo.GDArCameraService.java
其他类都只是测试API
\ No newline at end of file
目录:com.example.cameraservicedemo 下面的只是测试demo
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment