Log in or register to post comments

Take Screenshot

March 29, 2013 - 2:03pm #1

Hi ,

Please suggest should we use Android Camera API to take sceenshots or there is native api available in Vuforia for this functionality.

I am looking to create a button and take picture on click.

 

Regards

Vineet Aggarwal

 

 

Take Screenshot

June 4, 2015 - 10:12pm #26

HI,

I tried your code to take screen shot ( in android) , i could get a camera view with no overly image in it. how do i get a screenshot along with the overly image on top of the camera ?

Take Screenshot

April 16, 2013 - 6:25am #25

Then I don't have other suggestions about how to improve speed of capturing/saving.

 

Take Screenshot

April 16, 2013 - 3:14am #24

Hi Alessendro,

GLES20.GL_BGRA_EXT not exist in Android documnentation . Any other suggestions?

Regards

Vineet Aggarwal

Take Screenshot

April 15, 2013 - 4:10am #23

I see.

Have you tried with GL_BGRA_Ext ?

 

In OpenGL ES, in theory you should be able to use GL_BGRA_EXT (as a replacement for GL_BGRA, which is only available on desktop GL) ?
 
 
 

Take Screenshot

April 15, 2013 - 4:01am #22

Hi , 

Thanks for reply.

I am using high end device S3 .  I am developing app only for ICS nad JellyBean platforms

In Save PNG function ,  after getting the bitmap image we are just writing to outputstream so it should not take time.

From stackoverflow , i saw number of posts where i found glReadPixels is issue.

Some of the solutions there were using GL_BGRA mode but it's not available.

 

Regards

Vineet Aggarwal

Take Screenshot

April 15, 2013 - 3:55am #21

Hi,

I am not aware of other easy ways to capture an OpenGL screenshot, other than using the glReadPixels; I know that this method can be a bit slow, especially on non-high-end devices.

A question: do you have evidence that the bottleneck is just in the glReadPixels, or is it also the SavePNG function partially responsible of the slow performance ?

 

 

Take Screenshot

April 15, 2013 - 3:45am #20

Hi Alessandro ,

 

My code is to take screenshot is working fine. Thanks for your help.

I found glReadpixels slow .

After calling glreadpixels the screen pauses fro 1 second and then flickers.

Try to found on android forums but not get any answer. Can you please help.

 

GLES20.glReadPixels(x, 0, w, y + h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib);
 

Regards

Vineet Aggarwal

 

Take Screenshot

April 7, 2013 - 5:25am #19

Hi,

the error log shows that you are trying to drwa a recycled bitmap, which means that you probably have some code in which you dispose your bitmap;

this is a common Android error, you may want to search in some Android specific forums, for instance here is a thread about this topic:

http://stackoverflow.com/questions/12218976/cannot-draw-recycled-bitmaps-when-displaying-bitmaps-in-gallery-attached-to-ad

Take Screenshot

April 7, 2013 - 5:00am #18

The issue with Samsung galaxy S2 is resolved.

Thanks Moderators for fix.

But now I am getting issue in Nexus One.

 

Steps
 
open app/ marker is detected
tap to take photo
after 10 sec app crash
 
Log
04-05 15:38:17.351: E/AndroidRuntime(12513): java.lang.IllegalArgumentException: Cannot draw recycled bitmaps
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.GLES20Canvas.drawBitmap(GLES20Canvas.java:778)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.GLES20RecordingCanvas.drawBitmap(GLES20RecordingCanvas.java:117)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.widget.ImageView.onDraw(ImageView.java:961)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13458)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12409)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13182)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12407)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13182)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12407)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13182)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13461)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12409)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13182)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12407)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13182)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12407)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13182)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.drawChild(ViewGroup.java:2929)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.draw(View.java:13461)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.widget.FrameLayout.draw(FrameLayout.java:467)
04-05 15:38:17.351: E/AndroidRuntime(12513): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:2183)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12409)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.View.getDisplayList(View.java:12453)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1144)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewRootImpl.draw(ViewRootImpl.java:2147)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2019)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1830)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.Choreographer.doCallbacks(Choreographer.java:555)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.Choreographer.doFrame(Choreographer.java:525)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.os.Handler.handleCallback(Handler.java:615)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.os.Handler.dispatchMessage(Handler.java:92)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.os.Looper.loop(Looper.java:137)
04-05 15:38:17.351: E/AndroidRuntime(12513): at android.app.ActivityThread.main(ActivityThread.java:4745)
04-05 15:38:17.351: E/AndroidRuntime(12513): at java.lang.reflect.Method.invokeNative(Native Method)
04-05 15:38:17.351: E/AndroidRuntime(12513): at java.lang.reflect.Method.invoke(Method.java:511)
04-05 15:38:17.351: E/AndroidRuntime(12513): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
04-05 15:38:17.351: E/AndroidRuntime(12513): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)

 

Take Screenshot

April 3, 2013 - 12:57pm #17

Another thing you may also want to try is to add this line in your ImageTargetsRenderer.java, right after the renderFrame() line (in onDrawFrame()):

GLES20.glFinish();

(i.e. right before you call your code to save the PNG).

 

Take Screenshot

April 3, 2013 - 12:49pm #16

Ok; maybe try with using the actual width and height values, it might be that on the S2 the resolution is different when rendering (note: you can get the width and height values from the updateRendering function in ImageTargetsRenderer.java)

 

Take Screenshot

April 3, 2013 - 12:34pm #15

SavePNG(0, 0, 720, 1280, "image00" + VideoPlayback.IMG_COUNT + ".png");

 

Currenly i am setting static values. i  will set it to deveice screen size and width.

samsung galaxy s3 and samung galaxy s2 both have resolution 720x1280.

 

 

Take Screenshot

April 3, 2013 - 12:29pm #14

hi, can you share the code where you determine the width and height (that you then pass to the glReadPixels)

 

Take Screenshot

April 3, 2013 - 11:14am #13

Hi ,

 

I have tested my app and its working fine in Samsung Galaxy S3 and Galaxy Note \\

I am able to receive full image in both devices.

 

In samsung Galaxy S2 , I am getting 1/4 IMAGE . Rest of the screen is black.

Please help me to resolve issue on samsung galaxy S2.

Take Screenshot

April 2, 2013 - 11:57pm #12

You're welcome. Glad to see that you implemented and solved everything as intended.

Take Screenshot

April 2, 2013 - 11:55pm #11

Thanks Moderators

You really helped me

Take Screenshot

April 2, 2013 - 11:48pm #10

Hi ,

 

The issu was at my end.

 

I was providing width 100 , height 100  , now i m providing device height and width and its ok.

slow rendering was happening as by mistake i was trying to capture each frame. 

 

 

Take Screenshot

April 2, 2013 - 10:57pm #9

Thanks , I am now able to take image but now i am facing two new problems

 

1. The rending becomes too slow

2.  I am only capture part of view.

 

What can be possible reason?

 

Regards

Vineet Aggarwal

Take Screenshot

April 2, 2013 - 10:28pm #8

Hi, if you are rendering with OpenGL ES 2.0 (and not 1.1), you should replace this line:

 

 gl.glReadPixels(x, 0, w, y + h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);
 
with this:
 
 GLES20.glReadPixels(x, 0, w, y + h, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, ib);
 

That could be one problem.

 

 

 
 

 

Take Screenshot

April 2, 2013 - 1:38pm #7

Hi , 

Thanks for correct link . I use it but I am getting  the saved png as black.

What wrong i m doing

Here is the code

public void onDrawFrame(GL10 gl) {
		if (!mIsActive)
			return;

		for (int i = 0; i < VideoPlayback.VIDEO_TARGETS; i++) {
			if (mVideoPlayerHelper[i] != null) {
				if (mVideoPlayerHelper[i].isPlayableOnTexture()) {
				
					if (mVideoPlayerHelper[i].getStatus() == MEDIA_STATE.PLAYING)
						mVideoPlayerHelper[i].updateVideoData();

					
					mVideoPlayerHelper[i].getSurfaceTextureTransformMatrix(mTexCoordTransformationMatrix[i]);
					setVideoDimensions(i, mVideoPlayerHelper[i].getVideoWidth(),
							mVideoPlayerHelper[i].getVideoHeight(), mTexCoordTransformationMatrix[i]);
				}

				setStatus(i, mVideoPlayerHelper[i].getStatus().getNumericType());
			}
		}

		// Call our native function to render content
		renderFrame();

		if (VideoPlayback.CAMERA_CLICK)
	        SavePNG(0, 0, 400, 400, "test.png", gl);
		
		for (int i = 0; i < VideoPlayback.VIDEO_TARGETS; i++) {
		
			if (isTracking(i)) {
			
				if (mVideoPlayerHelper[i] != null)
					mVideoPlayerHelper[i].play(false, -1);

			} else {
			
				if (mVideoPlayerHelper[i] != null)
					mVideoPlayerHelper[i].pause();
				
			}
		}

	}



public void SavePNG(int x, int y, int w, int h, String name, GL10 gl) {
		Bitmap bmp = SavePixels(x, y, w, h, gl);
		try {
			File file = new File(Environment.getExternalStorageDirectory() + "/", name);

			try {
				file.createNewFile();
			} catch (IOException e1) {
				e1.printStackTrace();
			}
			FileOutputStream fos = new FileOutputStream(file);
			bmp.compress(CompressFormat.PNG, 100, fos);
			try {
				fos.flush();
			} catch (IOException e) {
				e.printStackTrace();
			}
			try {
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public Bitmap SavePixels(int x, int y, int w, int h, GL10 gl) {
		int b[] = new int[w * (y + h)];
		int bt[] = new int[w * h];
		IntBuffer ib = IntBuffer.wrap(b);
		ib.position(0);
		gl.glReadPixels(x, 0, w, y + h, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, ib);

		for (int i = 0, k = 0; i < h; i++, k++) {
			for (int j = 0; j < w; j++) {
				int pix = b[i * w + j];
				int pb = (pix >> 16) & 0xff;
				int pr = (pix << 16) & 0x00ff0000;
				int pix1 = (pix & 0xff00ff00) | pr | pb;
				bt[(h - k - 1) * w + j] = pix1;
			}
		}

		Bitmap sb = Bitmap.createBitmap(bt, w, h, Bitmap.Config.ARGB_8888);
		return sb;
	}

 

 

Take Screenshot

April 2, 2013 - 4:44am #6

Ok, if need to capture the AR view with the 3D objects (augmentation), then you need to use an OpenGL technique based on glReadPixels function;

the process is discussed in this thread:

https://developer.vuforia.com/forum/android/screen-capture-3d-object

 

Take Screenshot

April 1, 2013 - 7:52am #5

Hi

I understand and therefore not seeking any help on application specific code.

The problem is when i use android specific camera api it's capture the imagetarget but not the image augment on top of target.

Please help me how the capture the augmented image

Regards

Take Screenshot

April 1, 2013 - 7:37am #4

Hi, how to trigger the capture via a button click, and how to save it on sdcard is not a problem specific to Vuforia and the QCAR API, but it is application specific (and Android related),

the tutorial explains how to use the QCAR API to get the camera frame, the rest is beyond the scope of Vuforia and this forum.

 

Take Screenshot

March 31, 2013 - 7:21am #3

Hi,

Thanks for reply

 

I go through the tutorial but it seems i would not achieve my objective. My Objective is to on clicking button , user should able to 

 

1.  Capture Screenshot normally ( Like we normally does) and save in sdcard.

2.   If Image is displaying on top of ImageTarget , then Capture Image with background and save in sdcard

3.   If Video is displaying  on top of target, then Capture VideoFrame with background and save in sdcard.

 

I don't see any native method in the link you provided which i can call on button click to capture image.

 

Regards

Vineet Aggarwal

 

 

 

 

 

 

Take Screenshot

March 30, 2013 - 2:49am #2

Hi, you can use the Vuforia API to get the camera frame image, as explained here in detail and with code snippets to do that:

https://developer.vuforia.com/forum/faq/android-how-can-i-access-camera-image

That tutorial should guide you to achieve exactly what you are aiming for.

Log in or register to post comments