Android相机开发实战,面试题+笔记+项目实战

这篇具有很好参考价值的文章主要介绍了Android相机开发实战,面试题+笔记+项目实战。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

private SurfaceView mSurfaceView;

private SurfaceHolder mHolder;

private Size mPreviewSize;

private Size adapterSize;

//private List mSupportedPreviewSizes;

private Camera mCamera;

private boolean isSupportAutoFocus = false;

private Camera.Parameters parameters = null;

private Context mContext;

//private int mCurrentCameraId = 0;

private int screenWidth;

private int screenHeight;

CameraPreview(Context context, SurfaceView sv) {

super(context);

mContext = context;

mSurfaceView = sv;

mHolder = mSurfaceView.getHolder();

mHolder.addCallback(this);

mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

mHolder.setKeepScreenOn(true);

isSupportAutoFocus = context.getPackageManager().hasSystemFeature(

PackageManager.FEATURE_CAMERA_AUTOFOCUS);

DisplayMetrics dm = new DisplayMetrics();

((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(dm);

screenWidth = dm.widthPixels;

screenHeight = dm.heightPixels;

}

public void setCamera(Camera camera) {

mCamera = camera;

initCamera();

}

public void initCamera() {

if (mCamera != null) {

Camera.Parameters params = mCamera.getParameters();

//mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();

requestLayout();

if (mPreviewSize == null) {

mPreviewSize = findBestPreviewResolution();

}

if (adapterSize == null) {

adapterSize = findBestPictureResolution();

}

if (adapterSize != null) {

params.setPictureSize(adapterSize.width, adapterSize.height);

}

if (mPreviewSize != null) {

params.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

}

params.setPictureFormat(PixelFormat.JPEG);

List focusModes = params.getSupportedFocusModes();

if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) {

// set the focus mode

params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

// set Camera parameters

mCamera.setParameters(params);

}

setDispaly(params, mCamera);

//setCameraDisplayOrientation((Activity) mContext, mCurrentCameraId, mCamera);

mCamera.setParameters(params);

}

}

//控制图像的正确显示方向

private void setDispaly(Camera.Parameters parameters, Camera camera) {

if (Build.VERSION.SDK_INT >= 8) {

setDisplayOrientation(camera, 90);

} else {

parameters.setRotation(90);

}

}

//实现的图像的正确显示

private void setDisplayOrientation(Camera camera, int i) {

Method downPolymorphic;

try {

downPolymorphic = camera.getClass().getMethod(“setDisplayOrientation”,

new Class[]{int.class});

if (downPolymorphic != null) {

downPolymorphic.invoke(camera, new Object[]{i});

}

} catch (Exception e) {

e.printStackTrace();

}

}

public static void setCameraDisplayOrientation(Activity activity,

int cameraId, android.hardware.Camera camera) {

android.hardware.Camera.CameraInfo info =

new android.hardware.Camera.CameraInfo();

android.hardware.Camera.getCameraInfo(cameraId, info);

int rotation = activity.getWindowManager().getDefaultDisplay()

.getRotation();

int degrees = 0;

switch (rotation) {

case Surface.ROTATION_0:

degrees = 0;

break;

case Surface.ROTATION_90:

degrees = 90;

break;

case Surface.ROTATION_180:

degrees = 180;

break;

case Surface.ROTATION_270:

degrees = 270;

break;

}

int result;

if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {

result = (info.orientation + degrees) % 360;

result = (360 - result) % 360; // compensate the mirror

} else { // back-facing

result = (info.orientation - degrees + 360) % 360;

}

camera.setDisplayOrientation(result);

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);

final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);

setMeasuredDimension(width, height);

// if (mSupportedPreviewSizes != null) {

// mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);

// }

}

@Override

protected void onLayout(boolean changed, int l, int t, int r, int b) {

if (changed && getChildCount() > 0) {

final View child = getChildAt(0);

final int width = r - l;

final int height = b - t;

int previewWidth = width;

int previewHeight = height;

if (mPreviewSize != null) {

previewWidth = mPreviewSize.width;

previewHeight = mPreviewSize.height;

}

// Center the child SurfaceView within the parent.

if (width * previewHeight > height * previewWidth) {

final int scaledChildWidth = previewWidth * height / previewHeight;

child.layout((width - scaledChildWidth) / 2, 0,

(width + scaledChildWidth) / 2, height);

} else {

final int scaledChildHeight = previewHeight * width / previewWidth;

child.layout(0, (height - scaledChildHeight) / 2,

width, (height + scaledChildHeight) / 2);

}

}

}

public void surfaceCreated(SurfaceHolder holder) {

// The Surface has been created, acquire the camera and tell it where

// to draw.

try {

if (mCamera != null) {

mCamera.setPreviewDisplay(holder);

}

} catch (IOException e) {

if (null != mCamera) {

mCamera.release();

mCamera = null;

}

e.printStackTrace();

}

}

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

if (holder.getSurface() == null) {

return;

}

if (mCamera != null) {

Camera.Parameters parameters = mCamera.getParameters();

parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

mCamera.setParameters(parameters);

try {

mCamera.setPreviewDisplay(holder);

} catch (IOException e) {

e.printStackTrace();

}

mCamera.startPreview();

reAutoFocus();

}

}

public void surfaceDestroyed(SurfaceHolder holder) {

// Surface will be destroyed when we return, so stop the preview.

if (mCamera != null) {

mCamera.stopPreview();

}

}

/**

  • 最小预览界面的分辨率

*/

private static final int MIN_PREVIEW_PIXELS = 480 * 320;

/**

  • 最大宽高比差

*/

private static final double MAX_ASPECT_DISTORTION = 0.15;

/**

  • 找出最适合的预览界面分辨率

  • @return

*/

private Camera.Size findBestPreviewResolution() {

Camera.Parameters cameraParameters = mCamera.getParameters();

Camera.Size defaultPreviewResolution = cameraParameters.getPreviewSize();

List<Camera.Size> rawSupportedSizes = cameraParameters.getSupportedPreviewSizes();

if (rawSupportedSizes == null) {

return defaultPreviewResolution;

}

// 按照分辨率从大到小排序

List<Camera.Size> supportedPreviewResolutions = new ArrayList<Camera.Size>(rawSupportedSizes);

Collections.sort(supportedPreviewResolutions, new Comparator() {

@Override

public int compare(Camera.Size a, Camera.Size b) {

int aPixels = a.height * a.width;

int bPixels = b.height * b.width;

if (bPixels < aPixels) {

return -1;

}

if (bPixels > aPixels) {

return 1;

}

return 0;

}

});

StringBuilder previewResolutionSb = new StringBuilder();

for (Camera.Size supportedPreviewResolution : supportedPreviewResolutions) {

previewResolutionSb.append(supportedPreviewResolution.width).append(‘x’).append(supportedPreviewResolution.height)

.append(’ ');

}

// 移除不符合条件的分辨率

double screenAspectRatio = (double) screenWidth

/ screenHeight;

Iterator it = supportedPreviewResolutions.iterator();

while (it.hasNext()) {

Camera.Size supportedPreviewResolution = it.next();

int width = supportedPreviewResolution.width;

int height = supportedPreviewResolution.height;

// 移除低于下限的分辨率,尽可能取高分辨率

if (width * height < MIN_PREVIEW_PIXELS) {

it.remove();

continue;

}

// 在camera分辨率与屏幕分辨率宽高比不相等的情况下,找出差距最小的一组分辨率

// 由于camera的分辨率是width>height,我们设置的portrait模式中,width<height

// 因此这里要先交换然preview宽高比后在比较

boolean isCandidatePortrait = width > height;

int maybeFlippedWidth = isCandidatePortrait ? height : width;

int maybeFlippedHeight = isCandidatePortrait ? width : height;

double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;

double distortion = Math.abs(aspectRatio - screenAspectRatio);

if (distortion > MAX_ASPECT_DISTORTION) {

it.remove();

continue;

}

// 找到与屏幕分辨率完全匹配的预览界面分辨率直接返回

if (maybeFlippedWidth == screenWidth

&& maybeFlippedHeight == screenHeight) {

return supportedPreviewResolution;

}

}

// 如果没有找到合适的,并且还有候选的像素,则设置其中最大比例的,对于配置比较低的机器不太合适

if (!supportedPreviewResolutions.isEmpty()) {

Camera.Size largestPreview = supportedPreviewResolutions.get(0);

return largestPreview;

}

// 没有找到合适的,就返回默认的

return defaultPreviewResolution;

}

private Camera.Size findBestPictureResolution() {

Camera.Parameters cameraParameters = mCamera.getParameters();

List<Camera.Size> supportedPicResolutions = cameraParameters.getSupportedPictureSizes(); // 至少会返回一个值

StringBuilder picResolutionSb = new StringBuilder();

for (Camera.Size supportedPicResolution : supportedPicResolutions) {

picResolutionSb.append(supportedPicResolution.width).append(‘x’)

.append(supportedPicResolution.height).append(" ");

}

Camera.Size defaultPictureResolution = cameraParameters.getPictureSize();

// 排序

List<Camera.Size> sortedSupportedPicResolutions = new ArrayList<Camera.Size>(

supportedPicResolutions);

Collections.sort(sortedSupportedPicResolutions, new Comparator<Camera.Size>() {

@Override

public int compare(Camera.Size a, Camera.Size b) {

int aPixels = a.height * a.width;

int bPixels = b.height * b.width;

if (bPixels < aPixels) {

return -1;

}

if (bPixels > aPixels) {

return 1;

}

return 0;

}

});

// 移除不符合条件的分辨率

double screenAspectRatio = screenWidth

/ (double) screenHeight;

Iterator<Camera.Size> it = sortedSupportedPicResolutions.iterator();

while (it.hasNext()) {

Camera.Size supportedPreviewResolution = it.next();

int width = supportedPreviewResolution.width;

int height = supportedPreviewResolution.height;

// 在camera分辨率与屏幕分辨率宽高比不相等的情况下,找出差距最小的一组分辨率

// 由于camera的分辨率是width>height,我们设置的portrait模式中,width<height

// 因此这里要先交换然后在比较宽高比

boolean isCandidatePortrait = width > height;

int maybeFlippedWidth = isCandidatePortrait ? height : width;

int maybeFlippedHeight = isCandidatePortrait ? width : height;

double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;

double distortion = Math.abs(aspectRatio - screenAspectRatio);

if (distortion > MAX_ASPECT_DISTORTION) {

it.remove();

continue;

}

}

// 如果没有找到合适的,并且还有候选的像素,对于照片,则取其中最大比例的,而不是选择与屏幕分辨率相同的

if (!sortedSupportedPicResolutions.isEmpty()) {

return sortedSupportedPicResolutions.get(0);

}

// 没有找到合适的,就返回默认的

return defaultPictureResolution;

}

private Size getOptimalPreviewSize(List sizes, int w, int h) {

final double ASPECT_TOLERANCE = 0.1;

double targetRatio = (double) w / h;

if (sizes == null)

return null;

Size optimalSize = null;

double minDiff = Double.MAX_VALUE;

int targetHeight = h;

// Try to find an size match aspect ratio and size

for (Size size : sizes) {

double ratio = (double) size.width / size.height;

if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)

continue;

if (Math.abs(size.height - targetHeight) < minDiff) {

optimalSize = size;

minDiff = Math.abs(size.height - targetHeight);

}

}

// Cannot find the one match the aspect ratio, ignore the requirement

if (optimalSize == null) {

minDiff = Double.MAX_VALUE;

for (Size size : sizes) {

if (Math.abs(size.height - targetHeight) < minDiff) {

optimalSize = size;

minDiff = Math.abs(size.height - targetHeight);

}

}

}

return optimalSize;

}

public void reAutoFocus() {

if (isSupportAutoFocus) {

mCamera.autoFocus(new Camera.AutoFocusCallback() {

@Override

public void onAutoFocus(boolean success, Camera camera) {

}

});

}

}

public List getResolutionList() {

return mCamera.getParameters().getSupportedPreviewSizes();

}

public Camera.Size getResolution() {

Camera.Parameters params = mCamera.getParameters();

Camera.Size s = params.getPreviewSize();

return s;

}

/*public void setCurrentCameraId(int current) {

mCurrentCameraId = current;

}*/

//定点对焦的代码

public void pointFocus(MotionEvent event) {

mCamera.cancelAutoFocus();

parameters = mCamera.getParameters();

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {

//showPoint(x, y);

focusOnTouch(event);

}

mCamera.setParameters(parameters);

autoFocus();

}

//实现自动对焦

public void autoFocus() {

new Thread() {

@Override

public void run() {

try {

sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

if (mCamera == null) {

return;

}

mCamera.autoFocus(new Camera.AutoFocusCallback() {

@Override

public void onAutoFocus(boolean success, Camera camera) {

if (success) {

initCamera();//实现相机的参数初始化

}

}

});

}

};

}

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)

private void showPoint(int x, int y) {

if (parameters.getMaxNumMeteringAreas() > 0) {

List<Camera.Area> areas = new ArrayList<Camera.Area>();

WindowManager wm = (WindowManager) getContext()

.getSystemService(Context.WINDOW_SERVICE);

//xy变换了

int rectY = -x * 2000 / wm.getDefaultDisplay().getWidth() + 1000;

int rectX = y * 2000 / wm.getDefaultDisplay().getHeight() - 1000;

int left = rectX < -900 ? -1000 : rectX - 100;

int top = rectY < -900 ? -1000 : rectY - 100;

int right = rectX > 900 ? 1000 : rectX + 100;

int bottom = rectY > 900 ? 1000 : rectY + 100;

Rect area1 = new Rect(left, top, right, bottom);

areas.add(new Camera.Area(area1, 800));

parameters.setMeteringAreas(areas);

}

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);

}

@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)

public void focusOnTouch(MotionEvent event) {

Rect focusRect = calculateTapArea(event.getRawX(), event.getRawY(), 1f);

Rect meteringRect = calculateTapArea(event.getRawX(), event.getRawY(), 1.5f);

Camera.Parameters parameters = mCamera.getParameters();

parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

if (parameters.getMaxNumFocusAreas() > 0) {

List<Camera.Area> focusAreas = new ArrayList<Camera.Area>();

focusAreas.add(new Camera.Area(focusRect, 1000));

parameters.setFocusAreas(focusAreas);

}

if (parameters.getMaxNumMeteringAreas() > 0) {

List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

meteringAreas.add(new Camera.Area(meteringRect, 1000));

parameters.setMeteringAreas(meteringAreas);

}

mCamera.setParameters(parameters);

mCamera.autoFocus(this);

}

/**

  • Convert touch position x:y to {@link Camera.Area} position -1000:-1000 to 1000:1000.

*/

private Rect calculateTapArea(float x, float y, float coefficient) {

float focusAreaSize = 300;

int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();

int centerX = (int) (x / getResolution().width * 2000 - 1000);

int centerY = (int) (y / getResolution().height * 2000 - 1000);

int left = clamp(centerX - areaSize / 2, -1000, 1000);

int right = clamp(left + areaSize, -1000, 1000);

int top = clamp(centerY - areaSize / 2, -1000, 1000);

int bottom = clamp(top + areaSize, -1000, 1000);

return new Rect(left, top, right, bottom);

}

private int clamp(int x, int min, int max) {

if (x > max) {

return max;

}

if (x < min) {

return min;

}

return x;

}

@Override

public void onAutoFocus(boolean success, Camera camera) {

}

public void setNull() {

adapterSize = null;

mPreviewSize = null;

}

}

以下是CameraActivity类:

public class CameraActivity extends Activity implements View.OnTouchListener,OnClickListener {

public static final String CAMERA_PATH_VALUE1 = “PHOTO_PATH”;

public static final String CAMERA_PATH_VALUE2 = “PATH”;

public static final String CAMERA_TYPE = “CAMERA_TYPE”;

public static final String CAMERA_RETURN_PATH = “return_path”;

private int PHOTO_SIZE_W = 2000;

private int PHOTO_SIZE_H = 2000;

public static final int CAMERA_TYPE_1 = 1;

public static final int CAMERA_TYPE_2 = 2;

private final int PROCESS = 1;

private CameraPreview preview;

private Camera camera;

private Context mContext;

private View focusIndex;

private ImageView flashBtn;

private int mCurrentCameraId = 0; // 1是前置 0是后置

private SurfaceView mSurfaceView;

private CameraGrid mCameraGrid;

private int type = 1; //引用的矩形框

private Button mBtnSearch;

private Button mBtnTakePhoto;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

mContext = this;

//requestWindowFeature(Window.FEATURE_NO_TITLE);

//getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏

//getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//拍照过程屏幕一直处于高亮

setContentView(R.layout.camera_home);

type = getIntent().getIntExtra(CAMERA_TYPE, CAMERA_TYPE_2);

initView();

InitData();

}

private void initView() {

focusIndex = (View) findViewById(R.id.focus_index);

flashBtn = (ImageView) findViewById(R.id.flash_view);

mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);

mCameraGrid = (CameraGrid) findViewById(R.id.camera_grid);

mBtnSearch = (Button) findViewById(R.id.search);

mBtnTakePhoto = (Button) findViewById(R.id.takephoto);

}

private void InitData() {

preview = new CameraPreview(this, mSurfaceView);

preview.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,

LayoutParams.MATCH_PARENT));

((FrameLayout) findViewById(R.id.layout)).addView(preview);

preview.setKeepScreenOn(true);

mSurfaceView.setOnTouchListener(this);

mCameraGrid.setType(type);

}

private Handler handler = new Handler();

private void takePhoto() {

try {

camera.takePicture(shutterCallback, rawCallback, jpegCallback);

} catch (Throwable t) {

t.printStackTrace();

Toast.makeText(getApplication(), “拍照失败,请重试!”, Toast.LENGTH_LONG)

.show();

try {

camera.startPreview();

} catch (Throwable e) {

}

}

}

@Override

protected void onResume() {

super.onResume();

int numCams = Camera.getNumberOfCameras();

if (numCams > 0) {

try {

mCurrentCameraId = 0;

camera = Camera.open(mCurrentCameraId);

camera.startPreview();

preview.setCamera(camera);

preview.reAutoFocus();

} catch (RuntimeException ex) {

Toast.makeText(mContext, “未发现相机”, Toast.LENGTH_LONG).show();

}

}

}

@Override

protected void onPause() {

if (camera != null) {

camera.stopPreview();

preview.setCamera(null);

camera.release();

camera = null;

preview.setNull();

}

super.onPause();

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
android camera面试题,Android程序员,android,数码相机,笔记
android camera面试题,Android程序员,android,数码相机,笔记
android camera面试题,Android程序员,android,数码相机,笔记
android camera面试题,Android程序员,android,数码相机,笔记

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
android camera面试题,Android程序员,android,数码相机,笔记

推荐学习资料


  • 脑图
    android camera面试题,Android程序员,android,数码相机,笔记
    android camera面试题,Android程序员,android,数码相机,笔记
    android camera面试题,Android程序员,android,数码相机,笔记
    由于文章篇幅问题点击链接查看详细文章以及获取学习笔记:GitHub

s = Camera.getNumberOfCameras();

if (numCams > 0) {

try {

mCurrentCameraId = 0;

camera = Camera.open(mCurrentCameraId);

camera.startPreview();

preview.setCamera(camera);

preview.reAutoFocus();

} catch (RuntimeException ex) {

Toast.makeText(mContext, “未发现相机”, Toast.LENGTH_LONG).show();

}

}

}

@Override

protected void onPause() {

if (camera != null) {

camera.stopPreview();

preview.setCamera(null);

camera.release();

camera = null;

preview.setNull();

}

super.onPause();

}

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-xvpDDIQM-1710825578837)]
[外链图片转存中…(img-Zq9sR6SA-1710825578838)]
[外链图片转存中…(img-GnBFH99m-1710825578839)]
[外链图片转存中…(img-zAlqX13A-1710825578839)]

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-uh5VQEOV-1710825578839)]文章来源地址https://www.toymoban.com/news/detail-852934.html

推荐学习资料


  • 脑图
    [外链图片转存中…(img-fgLvLPbG-1710825578840)]
    [外链图片转存中…(img-1JDHMtTY-1710825578840)]
    [外链图片转存中…(img-rSA1uxOU-1710825578841)]
    由于文章篇幅问题点击链接查看详细文章以及获取学习笔记:GitHub

到了这里,关于Android相机开发实战,面试题+笔记+项目实战的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 使用Camera1实现相机预览、拍照、录像

    本文介绍如何从零开始,在 Android 中实现 Camera1 的接入,并在文末提供 Camera1Manager 工具类,可以用于快速接入 Camera1 。 Android Camera1 API 虽然已经被 Google 废弃,但有些场景下不得不使用。 并且 Camera1 返回的帧数据是 NV21 ,不像 Camera2 、 CameraX 那样,需要自己再转一层,才能得

    2024年02月08日
    浏览(47)
  • 十分钟实现 Android Camera2 相机预览

    因为工作中要使用 Android Camera2 API ,但因为 Camera2 比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,并在 CSDN 上记录了下,希望能帮助到更多的小伙伴。 Camera2 API 的包名是 android.hardware.camera2 ,是 Android 5.0 后推出的一套调用摄像头设备的接口

    2024年02月13日
    浏览(70)
  • 十分钟实现 Android Camera2 相机拍照

    因为工作中要使用 Android Camera2 API ,但因为 Camera2 比较复杂,网上资料也比较乱,有一定入门门槛,所以花了几天时间系统研究了下,并在 CSDN 上记录了下,希望能帮助到更多的小伙伴。 上篇文章 我们使用 Camera2 实现了相机预览的功能,这篇文章我们接着上文,来实现 Cam

    2024年02月11日
    浏览(63)
  • Android 使用Camera2 API 和 GLSurfaceView实现相机预览

    GLSurfaceView 和 SurfaceView 是 Android 中用于显示图像的两个视图类,它们在实现方式和使用场景上有一些区别。 实现方式:GLSurfaceView 基于 OpenGL ES 技术实现,可以通过 OpenGL ES 渲染图像。而 SurfaceView 则是通过基于线程的绘制方式,可以在独立的线程中进行绘制操作。 性能:由于

    2024年02月09日
    浏览(45)
  • flutter开发实战-自定义相机camera功能

    flutter开发实战-自定义相机camera功能。 Flutter 本质上只是一个 UI 框架,运行在宿主平台之上,Flutter 本身是无法提供一些系统能力,比如使用蓝牙、相机、GPS等,因此要在 Flutter 中调用这些能力就必须和原生平台进行通信。 实现相机功能,我们使用的是camera插件。 在pubspec.

    2024年02月15日
    浏览(49)
  • flutter开发实战-Camera自定义相机拍照功能实现

    flutter开发实战-Camera自定义相机拍照功能实现 在项目中使用image_picker插件时候,在android设备上使用无法默认设置前置摄像头(暂时不清楚什么原因),由于项目默认需要使用前置摄像头,所以最终采用自定义相机实现拍照功能。 在工程的iOS的info.plist文件中添加相机、麦克风

    2024年02月21日
    浏览(53)
  • Android中相机(Camera)画面旋转角度分析:手机摄像头的“正向”、手机画面自然方向、相机画面的偏转角度

    #.概述:     1.如同人眼看东西分上下一样,摄像头也有其“正向”,正常情况下,Android手机后置、前置摄像头的“正向”朝向为手机的“右侧”(默认如此,除非手机厂商修改设置)。 (这里运行代码做过测试发现,前置摄像头也是以右侧为正向,而不是有些资料上说的

    2024年02月14日
    浏览(77)
  • Android学习笔记 - Camera(1)

    在APP开发中会有很多业务使用到Camera,对于一些基础的功能,调用系统的拍摄功能就可以满足要求。但是需要自定义UI界面时,例如将摄像头捕获的视图展示在页面上的时候就需要使用到Camera这个类了。 本篇会介绍哪些知识点: 什么是SurfaceView?有什么作用?何为双缓冲机制

    2024年02月03日
    浏览(39)
  • 我的NPI项目之Android Camera (一) -- Camera选型

    在一个项目起草PRS的时候就应该定义Camera的硬件参数,例如接口类型,分辨率,PDAF,OIS等等。在正式进行Camera选型的时候,还要考虑到是国产还是日韩,美国的模块。生命周期,后期服务等等因素。 目前在高通4490平台上,硬件上是支持有三路CSI, 并且能够支持如下的camer

    2024年02月19日
    浏览(40)
  • 我的NPI项目之Android Camera (二) -- 核心部件之 Camera Sensor

    说到Camera模组,我们比较关心的是用的什么样的sensor? sensor的分辨率多少,sensor的像素多大,sensor是哪家生产的等等一些问题。今天,我们就穿越时间,将sensor的历史扒一扒。 Wikipedia先看一下:history of Camera Camera的历史大体可以分为三大部分 : 核心部件Sensor : Sensor是什么

    2024年02月19日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包