针对GPU框架opengl渲染的数据,我们只能从GLSurfaceView通过glReadPixels获取预览数据,转化为RGBA格式再dump下来,这个过程不同于dump从底层传入的YUV预览帧数据,以下就是dump GLSurfaceView的详细过程。
一、dump GPU框架渲染数据
glReadPixels方法
if(mCount%30 == 0)
{
//创建byte[]数组获取GPU渲染数据
byte[] Data = new byte[mOutputWidth * mOutputHeight * 4];
ByteBuffer buf = ByteBuffer.wrap(Data);
buf.order(ByteOrder.LITTLE_ENDIAN);
//通过glReadPixels方法获取GLSurfaceView内容
GLES20.glReadPixels(0, 0, mOutputWidth, mOutputHeight, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, buf);
//saveByteToFile(Data, "process");
Bitmap bmp = setBitmapPixel(null, mOutputWidth, mOutputHeight, Data);
saveRGBAtoPNGFile(bmp);
}
保存RGBA数据为YUV格式
public void saveByteToFile(byte[] data, String path) {
SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
String date = sDateFormat.format(new java.util.Date());
File mediaStorageDir = mActivity.getAndroidContext().getExternalFilesDir("DCIM");
File d = new File(mediaStorageDir, path);
//File d = new File("/storage/emulated/0/bitmap/");
File f = new File(d, date + ".yuv");
if (!d.exists()) {
d.mkdirs();
}
if (f.exists()) {
f.delete();
}
try {
FileOutputStream out = new FileOutputStream(f);
out.write(data);
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "CameraSaveBitmap saveBitmapToFileException:" + f.getAbsolutePath() + " Exception");
e.printStackTrace();
}
}
保存RGBA数据为PNG格式
1.将原始数组转为RGBA数据格式,且byte转为bitmap数据格式
import android.graphics.Color;
import android.graphics.Bitmap.Config;
public static Bitmap setBitmapPixel(Context context, int width, int height, byte[] data) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
int mBitmapWidth = bitmap.getWidth();
int mBitmapHeight = bitmap.getHeight();
for (int i = 0; i < mBitmapHeight; i++) {
for (int j = 0; j < mBitmapWidth; j++) {
int index = (i * mBitmapWidth + j) * 4;
int alpha = data[index + 3] & 0xff;
int r = data[index] & 0xff;
int g = data[index + 1] & 0xff;
int b = data[index + 2] & 0xff;
bitmap.setPixel(j, i, Color.argb(alpha, r, g, b));
}
}
return bitmap;
}
2.将bitmap数据直接png保存
public void saveRGBAtoPNGFile(Bitmap bmp) {
String path ="wsj_dump.png";
File f = new File("/data/local/tmp/anc/", path);
if (f.exists()) {
f.delete();
}
try {
Log.e(TAG,"FileOutputStream");
FileOutputStream out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
Log.e(TAG,"compress");
out.flush();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void saveBitmaptoFile(Bitmap bmp, String path) {
SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd-hh-mm-ss");
String date = sDateFormat.format(new java.util.Date());
File mediaStorageDir = mActivity.getAndroidContext().getExternalFilesDir("DCIM");
File d = new File(mediaStorageDir, path);
if (!d.exists()) {
d.mkdirs();
}
File f = new File(d, date + ".png");
if (f.exists()) {
f.delete();
}
try {
FileOutputStream out = new FileOutputStream(f);
bmp.compress(Bitmap.CompressFormat.PNG, 100, out);
Log.e(TAG,"compress");
out.flush();
out.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
文件保存路径为:
/data/media/0/Android/data/com.android.camera2/files/DCIM/process
另:可读写路径获取
相关代码如下:
public static final String DCIM =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString();
public static final String DIRECTORY = DCIM + "/Camera";
public static final File DIRECTORY_FILE = new File(DIRECTORY);
CameraUtil.saveBitmapToFile(defaultbitmap, getModuleCoverPicturePath());
最后存储的相关路径为:
data/user/0/com.android.camera2/files
总结:
dump数据除上述俩种方法外,还有在HAL层dump各个节点数据的方法,这个在后续会进行详细讲解,通过dump帧数据的方法可以让我们准确把握传入算法各个节点的帧的差异,可基于此进行各种不同情况的处理与问题解决。