Cocos2dx GL SurfaceView截屏 应用层实现

Cocos2dx GL SurfaceView截屏  应用层实现

环境:使用Cocosdx进行游戏开发,需要Android实现截屏分享功能,但JNI没有提供截图路径,所以需要Android应用层实现截屏功能


1.使用Activity的截屏方法

public class ScreenShot {  
  
	public static Bitmap takeScreenShot(Activity activity) {  
        // View是你需要截图的View  
        View view = activity.getWindow().getDecorView();  
        view.setDrawingCacheEnabled(true);  
        view.buildDrawingCache();  
        Bitmap b1 = view.getDrawingCache();  
  
        // 获取状态栏高度  
        Rect frame = new Rect();  
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);  
        int statusBarHeight = frame.top;  
  
        // 获取屏幕长和高  
        int width = activity.getWindowManager().getDefaultDisplay().getWidth();  
        int height = activity.getWindowManager().getDefaultDisplay()  
                .getHeight();  
        // 去掉标题栏  
        Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height  
                - statusBarHeight);  
        view.destroyDrawingCache();  
        return b;  
    }  
  
    private static void savePic(Bitmap b, File filePath) {  
        FileOutputStream fos = null;  
        try {  
            fos = new FileOutputStream(filePath);  
            if (null != fos) {  
                b.compress(Bitmap.CompressFormat.PNG, 100, fos);  
                fos.flush();  
                fos.close();  
            }  
        } catch (FileNotFoundException e) {  
            // e.printStackTrace();  
        } catch (IOException e) {  
            // e.printStackTrace();  
        }  
    }  
  
    public static void shoot(Activity a, File filePath) {  
        if (filePath == null) {  
            return;  
        }  
        if (!filePath.getParentFile().exists()) {  
            filePath.getParentFile().mkdirs();  
        }  
        ScreenShot.savePic(ScreenShot.takeScreenShot(a), filePath);  
    }  
}  


问题:截屏为黑屏。

原因:因为Activity和SurfaceView的页面绘制机制是不用的



2.使用surfaceView的截屏方法

Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
draw(canvas);

问题:截屏为白屏。

原因:因为cocos2dx项目,绘图是由CPP代码执行的,在Cocos2dxGLSurfaceView上绘图,所以不能使用一般SurfaceView的截图方法。


3.应用层。使用org.cocos2dx.lib中的Cocos2dxRenderer类中的GL10转为Bitmap


新建截屏类ShotScreenByGL10 ,将GL10转换为Bitmap

public class ShotScreenByGL10 {
	
	private static int width;
	private static int height;
	public static  GL10 gl;
	
	public static void setWidth(int width) {
		ShotScreenByGL10.width = width;
	}

	public static void setHeight(int height) {
		ShotScreenByGL10.height = height;
	}

	public static void setGl(GL10 gl) {
		ShotScreenByGL10.gl = gl;
	}

	public static Bitmap getShotScreenBitmap() {
		
		ByteBuffer buffer = ByteBuffer.allocateDirect(width * height * 4);
        gl.glReadPixels(0, 0, width, height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, buffer);
 
        // 上下逆なので、上下反転
        byte[] tmp1 = new byte[width * 4];
        byte[] tmp2 = new byte[width * 4];
        int h = (int) height / 2;
        for (int y = 0; y < h; y++) {
            buffer.position(y * width * 4);
            buffer.get(tmp1, 0, tmp1.length);
            buffer.position((height - 1 - y) * width * 4);
            buffer.get(tmp2, 0, tmp2.length);
            buffer.position((height - 1 - y) * width * 4);
            buffer.put(tmp1);
            buffer.position(y * width * 4);
            buffer.put(tmp2);
        }
        buffer.position(0);
        tmp1 = tmp2 = null;
 
        // Bitmapの作成
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        bitmap.copyPixelsFromBuffer(buffer);
 
        // 後片付け
        buffer = null;
        System.gc();

		
		return bitmap;
	}

}

在org.cocos2dx.lib中的Cocos2dxRenderer类中的onDrawFrame()方法中添加

ShotScreenByGL10.setGl(gl);
即对底层每一帧绘画的最新GL10进行保存,以便需要截屏时,将GL10转换成Bitmap


这样就能随时获取到最新的绘画GL10,然后将其转化为Bitmap,从而获取到截屏图片。


成功!!!

4.JNI层。在JNI层调用cocos2dx的截屏功能,将屏幕截取并保存到路径Path中,再将Path传递给JAVA应用层代码,最后在JAVA应用层根据Path获取图片,实现截屏分享功能。

但这样需要JNI那边进行截好图,供应用层调用

一般实现方法。


你可能感兴趣的:(Android问题)