public synchronized byte[] getPicture(int Width, int Height) throws InterruptedException {
FrameWidth = Width;
FrameHeight = Height;
try {
Log.i("B4A", "Try Mode.");
// while (!isPreviewOn) wait();
Log.i("B4A", "IsPreviewOn is True");
isDecoding = true;
Log.i("B4A", "Decoding is true.");
c.setOneShotPreviewCallback(this);
Log.i("B4A", "Callback Done.");
wait(5000);
Log.i("B4A", "Outside isDecoding.");
} catch (Exception e) {
Log.i("B4A", "An error occured.");
return null;
}
return mCurrentFrame;
}
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Try Mode.
IsPreviewOn is True
Decoding is true.
Callback Done.
i is : 0
Outside isDecoding.
<<<--------------- Waits 5 seconds here. (this text is not displayed in B4A)
main_mnufocusmode_click (java line: 287)
java.lang.NullPointerException
at anywheresoftware.b4a.agraham.byteconverter.ByteConverter.HexFromBytes(ByteConverter.java:237)
at com.rootsoft.streamnationstudio.main._mnufocusmode_click(main.java:287)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:104)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:88)
at com.rootsoft.streamnationstudio.main$B4AMenuItemsClickListener.onMenuItemClick(main.java:117)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:137)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:855)
at com.android.internal.view.menu.IconMenuView.invokeItem(IconMenuView.java:532)
at com.android.internal.view.menu.IconMenuItemView.performClick(IconMenuItemView.java:122)
at android.view.View$PerformClick.run(View.java:9210)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3652)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:862)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
at dalvik.system.NativeStart.main(Native Method)
java.lang.NullPointerException
In onPreviewFrame
Initialize raw2jpg
In raw2jpg.
Done with raw2jpg
Decoding is false.
Called as preview frames are displayed. This callback is invoked on the event thread open(int) was called from.
I may have found the problem. It is a sort of deadlock. From the documentation for Camera.PreviewCallback onPreviewFrame.
The callback can't run because the thread it wants to run on is blocked in getPicture. The application you took that code from presumably calls getPicture from a different thread than the one that opened the camera.
Your best bet is probably to let getPicture return and raise an event at the end of onPreviewFrame. As it runs on the main thread it looks like you can use raiseEvent rather than raiseEventFromDifferentThread.
No butIs there any documentation on ba.raiseEvent(null, eventName + "_ready", true);?
I don't know what that means either. Where is it from?As I don't know what all these things mean: "readyCount.addAndGet(1) == 2" etc
@SuppressWarnings("static-access")
public void Initialize(final BA ba, ViewGroup Panel, String EventName) {
this.ba = ba;
readyCount.set(0);
this.eventName = EventName.toLowerCase(BA.cul);
sv = new SurfaceView(ba.context);
anywheresoftware.b4a.BALayout.LayoutParams lp = new anywheresoftware.b4a.BALayout.LayoutParams(
0, 0, Panel.getLayoutParams().width,
Panel.getLayoutParams().height);
Panel.addView(sv, lp);
if (c != null) {
readyCount.set(1);
}
sv.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
sv.getHolder().setFixedSize(Panel.getLayoutParams().width,
Panel.getLayoutParams().height);
sv.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (readyCount.addAndGet(1) == 2) {
ba.raiseEvent(null, eventName + "_ready", true);
}
}
public void getPicture(int Width, int Height){
FrameWidth = Width;
FrameHeight = Height;
try {
Log.i("B4A", "Try Mode.");
Log.i("B4A", "IsPreviewOn is True");
isDecoding = true;
Log.i("B4A", "Decoding is true.");
c.setOneShotPreviewCallback(this);
Log.i("B4A", "Callback Done.");
Log.i("B4A", "Outside isDecoding.");
} catch (Exception e) {
Log.i("B4A", "An error occured.");
return;
}
return;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i("B4A", "In onPreviewFrame");
int width = FrameWidth;
int height = FrameHeight;
int[] temp = new int[width * height];
OutputStream out = new ByteArrayOutputStream();
Bitmap bm = null;
Log.i("B4A", "Initialize raw2jpg");
raw2jpg(temp, data, width, height);
bm = Bitmap.createBitmap(temp, width, height, Bitmap.Config.RGB_565);
bm.compress(CompressFormat.JPEG, 100, out);
mCurrentFrame = ((ByteArrayOutputStream) out).toByteArray();
isDecoding = false;
Log.i("B4A", "isDecoding false");
ba.raiseEvent(null, eventName + "_previewtaken", mCurrentFrame);
}
If that's working its because your event Sub takes no parameters so mCurrentFrame is being ignored. Parameters have to be passed in an Object array as I stated.and raiseEvent(this, eventName + "_somename", Object[] = { mCurrentFrame });
doesn't seem to work but
raiseEvent(this, eventName + "_somename", mCurrentFrame );
@Events(values = { "Ready (Success As Boolean)",
"PictureTaken (Data() As Byte)","PreviewTaken (Picture as Byte())" })
ba.raiseEvent(null, eventName + "_previewtaken", new Object[] { mCurrentFrame });
@Events(values = { "Ready (Success As Boolean)","PictureTaken (Data() As Byte)","PreviewTaken (Data() As Byte)" })
public void getPicture(int Width, int Height){
FrameWidth = Width;
FrameHeight = Height;
try {
Log.i("B4A", "Try Mode.");
Log.i("B4A", "IsPreviewOn is True");
isDecoding = true;
Log.i("B4A", "Decoding is true.");
c.setOneShotPreviewCallback(this);
Log.i("B4A", "Callback Done.");
Log.i("B4A", "Outside isDecoding.");
} catch (Exception e) {
Log.i("B4A", "An error occured.");
return;
}
return;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.i("B4A", "In onPreviewFrame");
int width = FrameWidth;
int height = FrameHeight;
int[] temp = new int[width * height];
OutputStream out = new ByteArrayOutputStream();
Bitmap bm = null;
Log.i("B4A", "Initialize raw2jpg");
raw2jpg(temp, data, width, height);
bm = Bitmap.createBitmap(temp, width, height, Bitmap.Config.RGB_565);
bm.compress(CompressFormat.JPEG, 100, out);
mCurrentFrame = ((ByteArrayOutputStream) out).toByteArray();
isDecoding = false;
Log.i("B4A", "isDecoding false");
ba.raiseEvent(null, eventName + "_previewtaken", data);
}
Sub mnuFocusMode_Click
Msgbox("Getting Picture.","")
camera1.getPicture(480,320)
's = b.HexFromBytes(camera1.getPicture(480,320))
Msgbox("s","")
End Sub
Sub Camera1_PreviewTaken (Data() As Byte)
Msgbox("on Preview Taken","")
s = b.HexFromBytes(Data)
Msgbox(s,"")
End Sub
sub Camera1_Preview
end sub
Sub Camera1_PreviewTaken (Success As Boolean, Data() as Byte, PictureFrame as Byte)
' As I want something to play with the success and Data bytes too.
End Sub
ba.raiseEvent(this, eventName + "_previewtaken", new Object[] { success, mCurrentFrame, pictureFrame } );
}
Why should there be another file? That Java file as it stands will compile to a library and raise an event. The rest is up to you.
The @Events attribute is only needed for IDE Intellisense support, I assumed you could do that.
To add parameters to the event just include them in the parameter Object array.
Sigh! I really don't know why I bother at timesB4X:ba.raiseEvent(this, eventName + "_previewtaken", new Object[] { success, mCurrentFrame, pictureFrame } ); }
Sub mnuFocusMode_Click
Msgbox("Getting Picture.","")
camera1.getPicture(480,320)
's = b.HexFromBytes(camera1.getPicture(480,320))
Msgbox("s","")
End Sub
Sub Camera1_PreviewTaken(mCurrentFrame() As Byte)
Msgbox("on Preview Taken","")
s = b.HexFromBytes(mCurrentFrame)
Msgbox(s,"")
End Sub
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?