मैं LogCat #onPreviewFrame()
कई बार लॉग कर करने की उम्मीद कर रहा हूँ, लेकिन यह केवल की तरह चयनित उपकरणों पर काम करता है:कैमरा onPreviewFrame
- Samsung Galaxy S6 (7.0)
- Samsung Galaxy S6 (6.0.1)
- एलजी लियोन (5.0.1)
लेकिन निम्नलिखित उपकरणों पर नहीं करता है:
public CameraSurfaceView(Context context, AttributeSet set) {
super(context, set);
Log.d(TAG, "CameraSurfaceView(context, set)");
// Get the Surface Holder
this.holder = this.getHolder();
this.holder.addCallback(this);
this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// Turn on the Camera
this.camera = Camera.open();
} catch (Exception ex) {
Log.e(TAG, "#surfaceCreated() error=" + ex.getMessage(), ex);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(TAG, "#surfaceChanged()");
if (holder.getSurface() == null) {
// preview surface does not exist
return;
}
if (camera == null) {
// camera does not exist
return;
}
// This allows us to make our own draw calls to this canvas
this.setWillNotDraw(false);
// Initialize canvas variables
previewPaint = new Paint();
// Initialize preview variables
deviceWidth = width;
deviceHeight = height;
Camera.Size previewSize = this.camera.getParameters().getPreviewSize();
previewWidth = previewSize.width;
previewHeight = previewSize.height;
previewBitmap = Bitmap.createBitmap(previewWidth, previewHeight, Bitmap.Config.ARGB_8888);
// Initialize Scale Variables
previewScaleMatrix = new Matrix();
previewScaleMatrix.setScale(deviceWidth/(float) previewWidth,
deviceHeight/(float) previewHeight, deviceWidth/2.0f, deviceHeight/2.0f);
// Initialize RenderScript variables
rs = RenderScript.create(getContext());
// RenderScript YUV to RGB
yuvToRgbScript = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
Type.Builder previewRgbaType =
new Type.Builder(rs, Element.RGBA_8888(rs)).setX(previewWidth).setY(previewHeight);
yuvToRgbOut = Allocation.createTyped(rs, previewRgbaType.create(), Allocation.USAGE_SCRIPT);
// RenderScript Invert
invertScript = new ScriptC_invert(rs);
invertOut = Allocation.createTyped(rs, yuvToRgbOut.getType(), Allocation.USAGE_SCRIPT);
// Set color effect to none
parameters.setColorEffect(Camera.Parameters.EFFECT_NONE);
camera.setParameters(parameters);
// Set the preview callback
Log.d(TAG, "#surfaceChanged() camera.setPreviewCallback()");
camera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.d(TAG, "#onPreviewFrame()");
}
});
// Start the camera preview
Log.d(TAG, "#surfaceChanged() camera.startPreview()");
camera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// Surface will be destroyed when replaced with a new screen
// Always make sure to release the Camera instance
if (camera != null) {
camera.setPreviewCallback(null);
camera.stopPreview();
camera.release();
camera = null;
}
}
मेरे LogCat प्रदर्शित करता है इस प्रकार है::
- एलजी जी -4 (6,0)
- Huawei 6X (7,0)
- Nexus 6P (7,0)
नीचे कोड स्निपेट है
D/CameraSurfaceView: #surfaceChanged()
D/CameraSurfaceView: #surfaceChanged() camera.setPreviewCallback()
D/CameraSurfaceView: #surfaceChanged() camera.startPreview()
ScriptC_invert
से है RenderScript
नमूना https://developer.android.com/guide/topics/renderscript/compute.html#writing-an-rs-kernel
और यहां तक कि अगर मैं सभी रेंडरस्क्रिप्ट सामान को हटा देता हूं, वही समस्या।
नोट::
एक ठीक मेरी surfaceChanged()
विधि में एक camera.setPreviewDisplay(holder)
की आवश्यकता होगी
मैं भी निम्नलिखित की कोशिश की है। लेकिन यह मेरे लिए एक और मुद्दा बनाने के बाद से मैं मुठभेड़ onPreviewFrame()
में एक holder.lockCanvas()
करने की ज़रूरत है और निम्न अपवाद हैं जाएगा:
E/SurfaceHolder: Exception locking surface
java.lang.IllegalArgumentException
at android.view.Surface.nativeLockCanvas(Native Method)
at android.view.Surface.lockCanvas(Surface.java:264)
at android.view.SurfaceView$4.internalLockCanvas(SurfaceView.java:842)
at android.view.SurfaceView$4.lockCanvas(SurfaceView.java:830)
at com.arcanys.ar.CameraSurfaceView.onPreviewFrame(CameraSurfaceView.java:204)
से कुछ चीज़ों पर मैं चूक या गलत कॉन्फ़िगर किया गया है हो सकता है।
यह एक सही कामकाज है। [setPreviewDisplay या setPreviewTexture] (https://stackoverflow.com/questions/16752454/setpreviewdisplay-vs-setpreviewtexture) एंड्रॉइड में अनिवार्य है, लेकिन कुछ डिवाइस इसे लागू नहीं करते हैं। –
बीटीडब्ल्यू, ** कैमरा 2 ** एपीआई पर स्विच करने पर विचार करें जब तक कि आपके अधिकांश लक्षित डिवाइस लॉलीपॉप से नीचे न हों। और यदि आप * बहिष्कृत * कैमरा एपीआई के साथ रहने का फैसला करते हैं, तो सुनिश्चित करें कि आप कैमरे को एक अलग हैंडलर थ्रेड में खोलें (ताकि कैमरा.ओपेन() और कॉलबैक यूआई थ्रेड पर भीड़ का कारण न बनें)। –
@AlexCohn आपकी सलाह के लिए धन्यवाद। हां, मैं प्री-लॉलीपॉप डिवाइस को भी लक्षित कर रहा हूं इसलिए मैं अभी भी बहिष्कृत कैमरा एपीआई का उपयोग कर रहा हूं। – dhagz