Cocos2dx GL SurfaceView截屏 应用层实现
java
环境:使用Cocosdx进行游戏开发,须要Android实现截屏分享功能,但JNI没有提供截图路径,因此须要Android应用层实现截屏功能canvas
1.使用Activity的截屏方法ui
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); } }
问题:截屏为黑屏。spa
缘由:由于Activity和SurfaceView的页面绘制机制是不用的code
2.使用surfaceView的截屏方法orm
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; } }
ShotScreenByGL10.setGl(gl);即对底层每一帧绘画的最新GL10进行保存,以便须要截屏时,将GL10转换成Bitmap
这样就能随时获取到最新的绘画GL10,而后将其转化为Bitmap,从而获取到截屏图片。
成功!!!
4.JNI层。在JNI层调用cocos2dx的截屏功能,将屏幕截取并保存到路径Path中,再将Path传递给JAVA应用层代码,最后在JAVA应用层根据Path获取图片,实现截屏分享功能。
但这样须要JNI那边进行截好图,供应用层调用
通常实现方法。