平面 YUV 420 图像由 640 x 480 字节的 Y 样本、320 x 240 字节的 U 样本和 320 x 240 字节的 V 样本组成。由于每个 2x2 块(而不是每个像素)只存在颜色信息,我假设所有图像大小和位置都是 2 的倍数。(否则会变得更加复杂。)
此外,我假设在 Y 和 U 之间或 U 和 V 样本之间的行尾没有填充。
void copyRect(unsigned char* targetImage, int targetWidth, int targetHeight,
unsigned char* sourceImage, int sourceWidth, int sourceHeight,
int sourceLeft, int sourceTop,
int width, int height,
int targetLeft, int targetTop)
{
// Y samples
unsigned char* tgt = targetImage + targetTop * targetWidth + targetLeft;
unsigned char* src = sourceImage + sourceTop * sourceWidth + sourceLeft;
for (int i = 0; i < height; i++) {
memcpy(tgt, src, width);
tgt += targetWidth;
src += sourceWidth;
}
// U samples
tgt = targetImage + targetHeight * targetWidth
+ (targetTop / 2) * (targetWidth / 2) + (targetLeft / 2);
src = sourceImage + sourceHeight * sourceWidth
+ (sourceTop / 2) * (sourceWidth / 2) + (sourceLeft / 2);
for (int i = 0; i < height / 2; i++) {
memcpy(tgt, src, width / 2);
tgt += targetWidth / 2;
src += sourceWidth / 2;
}
// V samples
tgt = targetImage + targetHeight * targetWidth + (targetHeight / 2) * (targetWidth / 2)
+ (targetTop / 2) * (targetWidth / 2) + (targetLeft / 2);
src = sourceImage + sourceHeight * sourceWidth + (sourceHeight / 2) * (sourceWidth / 2)
+ (sourceTop / 2) * (sourceWidth / 2) + (sourceLeft / 2);
for (int i = 0; i < height / 2; i++) {
memcpy(tgt, src, width / 2);
tgt += targetWidth / 2;
src += sourceWidth / 2;
}
}
我从未尝试编译代码。所以没有保证。
参数为:
targetImage:目标图片的像素数据,另一张图片复制到的地方
targetWidth, targetHeigt:目标图片的尺寸
sourceImage:源图片的像素数据,一部分复制到另一张图片中
sourceWidth, sourceHeight:源图片的尺寸
sourceLeft, sourceTop:要复制的区域的源图像的左上角
width,height:要复制的区域大小
targetLeft, targetTop:目标图像中的左上角位置,该区域被复制到该位置