android – 从YV12或NV12字节数组中裁剪图像

我实现了Camera.PreviewCallback,然后我将原始图像(YV12或NV12格式)作为字节数组.我正在寻找一种方法来裁剪该图像的一部分而不将其转换为位图.图像的裁剪部分将在其他位置流式传输(再次作为字节数组).

任何帮助赞赏.

公共类CameraAccess实现Camera.PreviewCallback,
        LoaderCallbackInterface {

private byte[] lastFrame;

@Override
public void onPreviewFrame(byte[] frame, Camera arg1) {
    synchronized(this) {
       this.lastFrame = frame;

    }
}

@Override
public byte[] cropFrame(Integer x, Integer y, Integer width, Integer height) {
    synchronized(this) {
       // how to crop directly from byte array?

    }
}

}

解决方法:

和图像作为字节数组只是图像中巨大数组的每个像素.它从左上角的像素开始,然后向右移动,然后向下移动(返回左侧).

所以要裁剪它只需要将你想要的像素复制到一个带有for循环的新字节数组:

Rect cropArea = ... //the are to crop
int currentPos = 0;
byte[] croppedOutput = new byte[cropArea.width() * cropArea.height()];
for(int y = 0; y < height; y++){
  for(int x = 0; x < width; x++){
      // here you compare if x and y are within the crop area you want
    if(cropArea.contains(x, y)){
       croppedOutput[currentPos] = frame[positionInArrayForXY(x, y)]
    }
  } 
}

你需要为方法positionInArrayForXY做一些额外的数学运算,这几乎是x * y,但是当值为零和东西时必须考虑到.

ps.:我相信每帧的帧数是1个字节,但不确定,所以如果它是每个像素2个字节,那就有一些额外的数学.但这个想法是一样的,你可以从中发展.

编辑:

回答你的评论:
不,这个东西没有标题,它只是直接的像素.这就是为什么它总是给你相机信息,所以你可以知道尺寸.

当我回答我希望YUV遵循RGB的数组顺序时,肯定它不能解决我的问题.

我做了一些额外的研究,here你可以看到进行YUV到RGB转换的方法,如果仔细检查,你会注意到它每12位使用一次,即1.5字节=> 921600 * 1.5 = 1382400

基于此,我可以想到几个方法:

>(最容易实现)将你的帧转换为RGB(我知道你指定你不想要,但它会更容易)并根据我的答案进行裁剪然后流式传输.
>(最大的开销,根本不那么容易)如果流的接收器必须在YUV中接收,执行上述操作但将其转换回YUV,在流之前执行链接方法的反转操作.
>(非常棘手的实现,但根据你的原始问题解决)根据我的示例代码,我发布的链接上的代码和每像素需要12位的事实开发代码与2 for循环做作物.

上一篇:android – 如何在ExoPlayer的PlayerView上使用类似的中心裁剪机制,但不在中心?


下一篇:c – 使用Leptonica API裁剪图片 – >或者使用哪个图像处理库?