java yuv 如何裁剪
YUV 图像裁剪方法
YUV 图像裁剪需要根据 YUV 格式(如 I420/NV12/NV21)处理不同分量的数据。以下以常见的 I420(YUV420P) 为例说明裁剪步骤:
获取原始参数
假设原始图像宽度为 srcWidth,高度为 srcHeight。目标裁剪区域左上角坐标为 (x, y),裁剪宽度为 cropWidth,高度为 cropHeight。

裁剪 Y 分量(亮度)
Y 分量是完整分辨率,每个像素占 1 字节。裁剪时直接从原始数据中按行复制:

byte[] srcY = ...; // 原始 Y 数据
byte[] dstY = new byte[cropWidth * cropHeight];
for (int row = 0; row < cropHeight; row++) {
System.arraycopy(
srcY, (y + row) * srcWidth + x, // 源起始位置
dstY, row * cropWidth, // 目标起始位置
cropWidth // 复制长度
);
}
裁剪 UV 分量(色度)
I420 的 UV 分量是 2x2 下采样的,分辨率减半。裁剪时需注意坐标和跨距:
// U/V 分量宽高为原图 1/2
int uvSrcWidth = srcWidth / 2;
int uvSrcHeight = srcHeight / 2;
int uvCropWidth = cropWidth / 2;
int uvCropHeight = cropHeight / 2;
byte[] srcU = ...; // 原始 U 数据
byte[] dstU = new byte[uvCropWidth * uvCropHeight];
for (int row = 0; row < uvCropHeight; row++) {
System.arraycopy(
srcU, (y/2 + row) * uvSrcWidth + x/2,
dstU, row * uvCropWidth,
uvCropWidth
);
}
// V 分量同理
NV12/NV21 处理
对于 NV12/NV21(半平面格式),UV 交错存储:
byte[] srcUV = ...; // NV12: UV交错数据
byte[] dstUV = new byte[cropWidth * cropHeight / 2];
int uvRowBytes = cropWidth; // 每行字节数(2字节 per UV像素)
for (int row = 0; row < cropHeight / 2; row++) {
System.arraycopy(
srcUV, (y/2 + row) * srcWidth + x,
dstUV, row * uvRowBytes,
uvRowBytes
);
}
注意事项
- 坐标对齐:YUV420 要求裁剪的
x、y、width、height必须是偶数,否则会破坏色度采样结构。 - 性能优化:大数据量时可使用
ByteBuffer或 JNI 加速处理。 - 格式差异:YUV422 或 YUV444 等格式需调整色度分量裁剪逻辑。






