Videoview Getdrawingcache Is Returning Black

VideoView getDrawingCache is returning black

From the docs for View#setDrawingCacheEnabled:

Enabling the drawing cache is similar
to setting a layer when hardware
acceleration is turned off. When
hardware acceleration is turned on,
enabling the drawing cache has no
effect on rendering because the system
uses a different mechanism for
acceleration which ignores the flag.
If you want to use a Bitmap for the
view, even when hardware acceleration
is enabled, see setLayerType(int,
android.graphics.Paint) for
information on how to enable software
and hardware layers.

It's possible that the VideoView operates with hardware acceleration and is bypassing the caching mechanism. A good source dive might shed some light.

Edit - this post seems to clear some things up:

Sorry, by its nature a SurfaceView does
not draw in the normal view hierarchy
update system, so it won't be drawn in
that.

(VideoView is a child of SurfaceView)

Android - getDrawingCache - black screen

You can draw your view to canvas-

pass your main layout reference to this method-

 Bitmap file = save(layout);

Bitmap save(View v)
{
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}

Saving View bitmap with getDrawingCache gives a black image

My problem was that my view was a TextView. The text on the TextView was black (naturally) and in the app the background looked white. However, I later recalled reading that a view's background is by default transparent so that whatever color is below shows through.

So I added android:background="@color/white" to the layout xml for the view and it worked. When I had been viewing the image before I had been looking at black text over a black background.

See the answer by @BraisGabin for an alternate way that does not require overdrawing the UI.

getDrawingCache() always returning null

Try calling buildDrawingCache() before getDrawingCache()

EDIT:
Call getDrawingCache(), after the page have loaded, instead of onCreate

getDrawingCache() always returns null

Similar question here more info here...

Problem appears to be that you can't access contents of a surfaceview - apparently you can capture the contents of an ImageView... I assume your using a surfaceView and thus encountering the same problem... If your willing to dig further this might help (from one of the above threads/topics)

If your not using a surfaceview then setLayerType might be your answer...

SurfaceView Returns black Screen in droidreader

I am using this, and its works fine in my case,

Here imageFrame is FrameLayout, root view of my View which I want to save as bitmap..

Bitmap saveBitmap = Bitmap.createBitmap(imageFrame.getWidth(), imageFrame.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(saveBitmap);
imageFrame.draw(c);

Try replacing imageFrame with your view.

EDIT:

    Date date = new Date();
File filename = new File(file.getAbsoluteFile(), "" + date.getTime() + ".jpg");
try
{
fOut = new FileOutputStream(filename);
saveBitmap.compress(Bitmap.CompressFormat.JPEG, 50, fOut);
try
{
fOut.flush();
fOut.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}

EDIT 2:

private void doDraw() {

int w = WIDTH_PX, h = HEIGHT_PX;
BitmapConfig conf = Bitmap.Config.ARGB_8888; // see other conf types
Bitmap bmp = Bitmap.createBitmap(w, h, conf); // this creates a MUTABLE bitmap
c = new Canvas(bmp);

Android Take Screenshot of Surface View Shows Black Screen

There is a great deal of confusion about this, and a few correct answers.

Here's the deal:

  1. A SurfaceView has two parts, the Surface and the View. The Surface is on a completely separate layer from all of the View UI elements. The getDrawingCache() approach works on the View layer only, so it doesn't capture anything on the Surface.

  2. The buffer queue has a producer-consumer API, and it can have only one producer. Canvas is one producer, GLES is another. You can't draw with Canvas and read pixels with GLES. (Technically, you could if the Canvas were using GLES and the correct EGL context was current when you went to read the pixels, but that's not guaranteed. Canvas rendering to a Surface is not accelerated in any released version of Android, so right now there's no hope of it working.)

  3. (Not relevant for your case, but I'll mention it for completeness:) A Surface is not a frame buffer, it is a queue of buffers. When you submit a buffer with GLES, it is gone, and you can no longer read from it. So if you were rendering with GLES and capturing with GLES, you would need to read the pixels back before calling eglSwapBuffers().

With Canvas rendering, the easiest way to "capture" the Surface contents is to simply draw it twice. Create a screen-sized Bitmap, create a Canvas from the Bitmap, and pass it to your draw() function.

With GLES rendering, you can use glReadPixels() before the buffer swap to grab the pixels. There's a (less-expensive than the code in the question) implementation of the grab code in Grafika; see saveFrame() in EglSurfaceBase.

If you were sending video directly to a Surface (via MediaPlayer) there would be no way to capture the frames, because your app never has access to them -- they go directly from mediaserver to the compositor (SurfaceFlinger). You can, however, route the incoming frames through a SurfaceTexture, and render them twice from your app, once for display and once for capture. See this question for more info.

One alternative is to replace the SurfaceView with a TextureView, which can be drawn on like any other Surface. You can then use one of the getBitmap() calls to capture a frame. TextureView is less efficient than SurfaceView, so this is not recommended for all situations, but it's straightforward to do.

If you were hoping to get a composite screen shot containing both the Surface contents and the View UI contents, you will need to capture the Canvas as above, capture the View with the usual drawing cache trick, and then composite the two manually. Note this won't pick up the system parts (status bar, nav bar).

Update: on Lollipop and later (API 21+) you can use the MediaProjection class to capture the entire screen with a virtual display. There are some trade-offs with this approach, e.g. you're capturing the rendered screen, not the frame that was sent to the Surface, so what you get may have been up- or down-scaled to fit the window. In addition, this approach involves an Activity switch since you have to create an intent (by calling createScreenCaptureIntent on the ProjectionManager object) and wait for its result.

If you want to learn more about how all this stuff works, see the Android System-Level Graphics Architecture doc.



Related Topics



Leave a reply



Submit