//==========================================\
标准有in memory相反的函数:
// ABGR little endian (rgba in memory)
如:
ABGRToARGB
ABGRToI420
BGRAToARGB
RGBAToARGB
......
glreadPixels(....GL_RGBA..)内存中真正是rgba格式;
调用带有上面标记的函数需要使用:ABGRTo...,
绝不能使用:RGBATo...
如ABGRToARGB调用后dest内存区域真正格式是:bgra,即RB互换;
但名字ARGB并无混淆,可以继续调用其他函数没问题,如:ARGBToNV21,dest内存区域真格式是:nv21
//==========================================\
Start & stride:
PStart=帧起始
size=w*h
RGBA:
PStart; stride: w * 4
I420:
Y: PStart; stride: w
U: PStart+size; stride: w/ 2
V: PStart +size* 5/ 4; stride: w/ 2
NV21
Y: PStart; stride: w
VU: PStart+size; stride: w
//==========================================\
保存帧函数:
C++:
#include<sstream>
int writeData2File( const void *buf, int size, int cnt) {
stringstream ss;
ss << cnt;
string s1 = "/mnt/sdcard/origin_20180109_";
string s = ss.str();
string s2 = ".rgba";
string sss = s1 + s + s2;
FILE *fp1 = fopen(sss.c_str(), "a+");
if (fp1==0) { printf("can't open file\n"); return -1;}
fseek(fp1, 0, SEEK_END);
fwrite(buf, size * 4, 1, fp1);
fclose(fp1);
return 0;
}
int writeData2File(const char *filename, const void *data, int size)
{
if (filename == nullptr || data == nullptr || size <= 0)
{
return -1;
}
FILE *fp = fopen(filename, "wb+");
if (fp == NULL)
{
// LOGE("Can not open file : %s!", filename);
return -1;
}
fwrite(data, size, 1, fp);
fclose(fp);
return 0;
}
Java
void saveYUVBytes2SDcard(byte[] yuvBytes) {
final String fileName = "Frame_" + System.currentTimeMillis() + ".yuv";
File file = new File(Environment.getExternalStorageDirectory(), fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file.getAbsolutePath());
fos.write(yuvBytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
void saveYUVBytes2Png2SDcard(byte[] yuvBytes, int w, int h) {
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
final Bitmap bitmap = convertYUVBytes2Bmp(yuvBytes, w, h);
final String fileName = "Frame_" + System.currentTimeMillis() + ".png";
new Thread(new Runnable() {
@Override
public void run() {
try {
saveBmp2PNGSDCard(fileName, bitmap);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bitmap != null) {
bitmap.recycle();
// bitmap = null;
}
}
}
}).start();
}
}
Bitmap convertYUVBytes2Bmp(byte[] yuv, int mWidth, int mHeight) {
YuvImage image = new YuvImage(yuv, ImageFormat.NV21, mWidth, mHeight, null);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, mWidth, mHeight), 100, stream);
Bitmap bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
try {
stream.flush();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return bmp;
}
private void saveBmp2PNGSDCard(String filename, Bitmap bmp) throws IOException {
File file = new File(Environment.getExternalStorageDirectory(), filename);
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(file));
bmp.compress(Bitmap.CompressFormat.PNG, 90, bos);
bmp.recycle();
bmp = null;
} finally {
if (bos != null) bos.close();
}
final String info = "Save frame to:" +
Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + filename;
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Activity.this, info, Toast.LENGTH_LONG).show();
}
});
}













网友评论