转载1:https://blog.csdn.net/qq1137830424/article/details/81980673
在调Camera的时候有个回调方法onPreviewFrame是返回摄像头每一帧的图像数据的,当我们需要对图像数据做处理时就需要Nv21转Bitmap,下面介绍两种方式第一种方式只需要几毫秒时间,第二种方式需要几十毫秒。
第一种方式(高效)
package com.my.camerademo;
import android.content.Context;
import android.graphics.Bitmap;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicYuvToRGB;
import android.renderscript.Type;
public class NV21ToBitmap {
private RenderScript rs;
private ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic;
private Type.Builder yuvType, rgbaType;
private Allocation in, out;
public NV21ToBitmap(Context context) {
rs = RenderScript.create(context);
yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
}
public Bitmap nv21ToBitmap(byte[] nv21, int width, int height){
if (yuvType == null){
yuvType = new Type.Builder(rs, Element.U8(rs)).setX(nv21.length);
in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(width).setY(height);
out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
}
in.copyFrom(nv21);
yuvToRgbIntrinsic.setInput(in);
yuvToRgbIntrinsic.forEach(out);
Bitmap bmpout = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
out.copyTo(bmpout);
return bmpout;
}
}
第二种方式
private static Bitmap nv21ToBitmap(byte[] nv21, int width, int height) {
Bitmap bitmap = null;
try {
YuvImage image = new YuvImage(nv21, ImageFormat.NV21, width, height, null);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
image.compressToJpeg(new Rect(0, 0, width, height), 80, stream);
bitmap = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size());
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
转载2: https://blog.csdn.net/xh2009cn/article/details/44258715
旋转NV21且不出现翻转
private static void yuv420spRotate90(byte[] des, byte[] src,
int width, int height) {
int wh = width * height;
int k = 0;
for(int i = 0; i < width; i++) {
for(int j = height - 1; j >= 0; j--)
{
des[k] = src[width * j + i];
k++;
}
}
for(int i = 0; i < width; i += 2) {
for(int j = height / 2 - 1; j >= 0; j--)
{
des[k] = src[wh+ width * j + i];
des[k+1] = src[wh + width * j + i + 1];
k+=2;
}
}
}
private static void YUV420spRotate180(byte[] des,byte[] src,int width,int height)
{
int n = 0;
int uh = height >> 1;
int wh = width * height;
//copy y
for(int j = height - 1; j >= 0; j--)
{
for(int i = width - 1; i >= 0; i--)
{
des[n++] = src[width * j + i];
}
}
for(int j = uh - 1;j >= 0; j--)
{
for(int i = width - 1; i > 0; i -= 2)
{
des[n] = src[wh + width * j + i - 1];
des[n + 1] = src[wh + width * j + i];
n += 2;
}
}
}
private static void YUV420spRotate270(byte[] des,byte[] src,int width,int height)
{
int n = 0;
int uvHeight = height >> 1;
int wh = width * height;
//copy y
for(int j = width - 1; j >= 0; j--)
{
for(int i = 0; i < height;i++)
{
des[n++] = src[width * i + j];
}
}
for(int j = width - 1; j > 0;j -= 2)
{
for(int i = 0; i < uvHeight; i++)
{
des[n++] = src[wh + width * i + j - 1];
des[n++] = src[wh + width * i + j];
}
}
}