我实现了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循环做作物.