我对CartoonifierApp.java文件进行了一些小修改(见下文),以便我可以使用OpenCV Manager应用程序静态加载漫画器库(原始代码抛出了UnsatisfiedLinkError).
我面临的问题是当我将应用程序加载到我的Galaxy Nexus(Android 4.1.1)上时,我得到一个空的黑屏.我的LogCat说:
@H_403_8@E/BufferQueue(4744): [unnamed-4744-0] setBufferCount: SurfaceTexture
has been abandoned! E/Cartoonifier::SurfaceView(4744):
startPreview() Failed
我认为这是一个记忆问题.我知道cpp代码可以工作,因为它在我的计算机上运行良好 – 虽然在相对较新的笔记本电脑(华硕U46E)上渲染很慢.
我不知道如何解决这个问题.我找到的唯一有用的建议是here.如果我在CatoonifierVewBase.java中替换我的setPreview方法
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) mCamera.setPreviewTexture( new SurfaceTexture(10) ); else mCamera.setPreviewDisplay(null);
同
mCamera.setPreviewDisplay(mHolder);
然后发生的事情是相机正常工作,我可以通过触摸屏幕保存卡通图像.请注意,这并不是理想的结果,因为我想在相机预览上不断地对图像进行漫画.相机只是工作,因为我没有写到表面视图(至少这是我的理解).前面提到的site中的答案有一些解决方法,但我不知道他在说什么.
顺便说一句,我已经尝试了所有OpenCV4Android应用程序示例,它们的工作正常.我也在使用OpenCV版本2.4.3. API级别目标是15.
完整Logcat:
@H_403_8@12-22 15:33:07.966: I/CartoonifierApp(5999): Instantiated new class
com.Cartoonifier.CartoonifierApp 12-22 15:33:07.966:
I/CartoonifierApp(5999): called onCreate 12-22 15:33:07.966:
I/CartoonifierApp(5999): Trying to load OpenCV library 12-22
15:33:07.982: I/Cartoonifier::SurfaceView(5999): Instantiated new
class com.Cartoonifier.CartoonifierView 12-22 15:33:07.990:
I/CartoonifierApp(5999): onResume 12-22 15:33:07.990:
I/Cartoonifier::SurfaceView(5999): openCamera 12-22 15:33:07.990:
I/Cartoonifier::SurfaceView(5999): releaseCamera 12-22 15:33:08.099:
D/OpenCVManager/Helper(5999): Service connection created 12-22
15:33:08.099: D/OpenCVManager/Helper(5999): Trying to get library path
12-22 15:33:08.138: D/OpenCVManager/Helper(5999): Trying to get
library list 12-22 15:33:08.169: D/OpenCVManager/Helper(5999): Library
list: “” 12-22 15:33:08.169: D/OpenCVManager/Helper(5999): First
attempt to load libs 12-22 15:33:08.169: D/OpenCVManager/Helper(5999):
Trying to init OpenCV libs 12-22 15:33:08.169:
D/OpenCVManager/Helper(5999): Trying to load library
/data/data/org.opencv.engine/lib/libopencv_java.so 12-22 15:33:08.169:
D/dalvikvm(5999): Trying to load lib
/data/data/org.opencv.engine/lib/libopencv_java.so 0x41936a40 12-22
15:33:08.193: D/dalvikvm(5999): Added shared lib
/data/data/org.opencv.engine/lib/libopencv_java.so 0x41936a40 12-22
15:33:08.193: D/OpenCVManager/Helper(5999): OpenCV libs init was ok!
12-22 15:33:08.193: D/OpenCVManager/Helper(5999): First attempt to
load libs is OK 12-22 15:33:08.193: D/OpenCVManager/Helper(5999): Init
finished with status 0 12-22 15:33:08.193:
D/OpenCVManager/Helper(5999): Unbind from service 12-22 15:33:08.200:
D/OpenCVManager/Helper(5999): Calling using callback 12-22
15:33:08.200: I/CartoonifierApp(5999): OpenCV loaded successfully
12-22 15:33:08.200: D/dalvikvm(5999): Trying to load lib
/data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40 12-22
15:33:08.200: D/dalvikvm(5999): Added shared lib
/data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40 12-22
15:33:08.200: D/dalvikvm(5999): No JNI_OnLoad found in
/data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40,
skipping init 12-22 15:33:08.200: D/OpenCVManager/Helper(5999):
Service connection created 12-22 15:33:08.200:
D/OpenCVManager/Helper(5999): Trying to get library path 12-22
15:33:08.232: D/OpenCVManager/Helper(5999): Trying to get library list
12-22 15:33:08.271: D/OpenCVManager/Helper(5999): Library list: “”
12-22 15:33:08.271: D/OpenCVManager/Helper(5999): First attempt to
load libs 12-22 15:33:08.271: D/OpenCVManager/Helper(5999): Trying to
init OpenCV libs 12-22 15:33:08.271: D/OpenCVManager/Helper(5999):
Trying to load library
/data/data/org.opencv.engine/lib/libopencv_java.so 12-22 15:33:08.271:
D/dalvikvm(5999): Trying to load lib
/data/data/org.opencv.engine/lib/libopencv_java.so 0x41936a40 12-22
15:33:08.271: D/dalvikvm(5999): Shared lib
‘/data/data/org.opencv.engine/lib/libopencv_java.so’ already loaded in
same CL 0x41936a40 12-22 15:33:08.271: D/OpenCVManager/Helper(5999):
OpenCV libs init was ok! 12-22 15:33:08.271:
D/OpenCVManager/Helper(5999): First attempt to load libs is OK
12-22 15:33:08.271: D/OpenCVManager/Helper(5999): Init finished with status 0
12-22 15:33:08.271: D/OpenCVManager/Helper(5999): Unbind from service
12-22 15:33:08.271: D/OpenCVManager/Helper(5999): Calling using callback
12-22 15:33:08.271: I/CartoonifierApp(5999): OpenCV loaded successfully
12-22 15:33:08.279: D/dalvikvm(5999): Trying to load lib /data/data/com.Cartoonifier/lib/libcartoonifier.so 0x41936a40
12-22 15:33:08.279: D/dalvikvm(5999): Shared lib ‘/data/data/com.Cartoonifier/lib/libcartoonifier.so’ already loaded in same CL 0x41936a40
12-22 15:33:08.302: I/Cartoonifier::SurfaceView(5999): surfaceCreated
12-22 15:33:08.302: I/Cartoonifier::SurfaceView(5999): surfaceChanged(). Window size: 1196×670
12-22 15:33:08.302: I/Cartoonifier::SurfaceView(5999): setupCamera(1196×670)
12-22 15:33:08.302: I/Cartoonifier::SurfaceView(5999): Starting processing thread
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 1920×1080
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 1280×720
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 960×720
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 800×480
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 720×576
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 720×480
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 768×576
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 640×480
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 320×240
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 352×288
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 240×160
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 176×144
12-22 15:33:08.310: I/Cartoonifier::SurfaceView(5999): Found Camera Resolution 128×96
12-22 15:33:08.318: I/Cartoonifier::SurfaceView(5999): Chosen Camera Preview Size: 1280×720
12-22 15:33:08.333: D/dalvikvm(5999): GC_FOR_ALLOC freed 131K,2% free 10807K/11011K,paused 13ms,total 13ms
12-22 15:33:08.333: I/dalvikvm-heap(5999): Grow heap (frag case) to 11.902MB for 1382416-byte allocation
12-22 15:33:08.357: D/dalvikvm(5999): GC_CONCURRENT freed 1K,3% free 12156K/12423K,paused 12ms+1ms,total 24ms
12-22 15:33:08.357: D/dalvikvm(5999): WAIT_FOR_CONCURRENT_GC blocked 11ms
12-22 15:33:08.365: D/dalvikvm(5999): GC_FOR_ALLOC freed 0K,paused 9ms,total 9ms
12-22 15:33:08.372: I/dalvikvm-heap(5999): Grow heap (frag case) to 13.219MB for 1382416-byte allocation
12-22 15:33:08.388: D/dalvikvm(5999): GC_CONCURRENT freed 0K,3% free 13506K/13831K,paused 11ms+1ms,total 21ms
12-22 15:33:08.388: D/dalvikvm(5999): WAIT_FOR_CONCURRENT_GC blocked 7ms
12-22 15:33:08.404: D/dalvikvm(5999): GC_FOR_ALLOC freed <1K,total 10ms
12-22 15:33:08.411: I/dalvikvm-heap(5999): Grow heap (frag case) to 16.735MB for 3686416-byte allocation
12-22 15:33:08.427: D/dalvikvm(5999): GC_CONCURRENT freed <1K,3% free 17106K/17479K,total 22ms
12-22 15:33:08.427: D/dalvikvm(5999): WAIT_FOR_CONCURRENT_GC blocked 10ms
12-22 15:33:08.443: D/dalvikvm(5999): GC_FOR_ALLOC freed <1K,paused 10ms,total 10ms
12-22 15:33:08.450: I/dalvikvm-heap(5999): Grow heap (frag case) to 20.250MB for 3686416-byte allocation
12-22 15:33:08.466: D/dalvikvm(5999): GC_CONCURRENT freed 0K,2% free 20706K/21127K,paused 12ms+2ms,total 22ms
12-22 15:33:08.466: D/dalvikvm(5999): WAIT_FOR_CONCURRENT_GC blocked 5ms
12-22 15:33:08.466: I/Cartoonifier::SurfaceView(5999): start preview
12-22 15:33:08.497: E/BufferQueue(5999): [unnamed-5999-0] setBufferCount: SurfaceTexture has been abandoned!
12-22 15:33:08.505: E/Cartoonifier::SurfaceView(5999): mCamera.startPreview() Failed
来自CartoonifierApp.java的片段显示我的修改
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) { @Override public void onManagerConnected(int status) { switch (status) { case LoaderCallbackInterface.SUCCESS: { Log.i(TAG,"OpenCV loaded successfully"); // Load native library after(!) OpenCV initialization System.loadLibrary("cartoonifier"); } break; default: { super.onManagerConnected(status); } break; } } }; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { Log.i(TAG,"called onCreate"); super.onCreate(savedInstanceState); Log.i(TAG,"Trying to load OpenCV library"); if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3,this,mLoaderCallback)) { Log.e(TAG,"Cannot connect to OpenCV Manager"); } requestWindowFeature(Window.FEATURE_NO_TITLE); mView = new CartoonifierView(this); setContentView(mView); // Call our "onTouch()" callback function whenever the user touches the screen. mView.setOnTouchListener(this); } @Override protected void onPause() { Log.i(TAG,"onPause"); super.onPause(); mView.releaseCamera(); } @Override public void onResume() { super.onResume(); Log.i(TAG,"onResume"); if (!OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_3,"Cannot connect to OpenCV Manager"); } if( !mView.openCamera() ) { AlertDialog ad = new AlertDialog.Builder(this).create(); ad.setCancelable(false); // This blocks the 'BACK' button ad.setMessage("Fatal error: can't open camera!"); /*ad.setButton("OK",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int which) { dialog.dismiss(); finish(); } }); */ ad.show(); } }
解决方法
@H_502_165@ 这个问题不久前在OpenCV中得到了解决.不确定它是应用程序还是操作系统错误.问题是调用Bitmap.createBitmap会分离用于可视化的SurfaceTexture对象.
解决方法是修改基本View类的setupCamera方法并进行更改
try { setPreview(); } catch (IOException e) { Log.e(TAG,"mCamera.setPreviewDisplay/setPreviewTexture fails: " + e); } /* Notify that the preview is about to be started and deliver preview size */ onPreviewStarted(params.getPreviewSize().width,params.getPreviewSize().height);
至
/* Notify that the preview is about to be started and deliver preview size */ onPreviewStarted(params.getPreviewSize().width,params.getPreviewSize().height); try { setPreview(); } catch (IOException e) { Log.e(TAG,"mCamera.setPreviewDisplay/setPreviewTexture fails: " + e); }
(线的顺序改变了)