一 转换方法
黑色是R,G,B都是0,因此Y通道是0,UV通道都是128
二 方法
// Correction of abscissa according to width
void fix_x(int &x, int width) {
if (x < 0) {
x = 0;
}
else if (x >= width) {
x = width - 1;
}
}
void fix_y(int &y, int height) {
if (y < 0) {
y = 0;
}
else if (y >= height) {
y = height - 1;
}
}
// Correct rectangular area according to image width and height
bool fix(int &left, int &top, int &right, int &bottom, int width, int height) {
fix_x(left, width);
fix_x(right, width);
fix_y(top, height);
fix_y(bottom, height);
int w = right - left;
int h = bottom - top;
if (w <= 0 || h <= 0) {
return false;
}
return true;
}
// blacken the designated area of nv12 image
// left:Abscissa of upper left corner of rectangular area
// top:Vertical coordinate of upper left corner of rectangular area
// right:Abscissa of lower right corner of rectangular area
// bottom:Vertical coordinate of the lower right corner of the rectangular area
// width:Original image width
// height:Original image height
// ppu8Plane_y:Y channel address
// ppu8Plane_uv:UV channel address
void blackening_nv12(int left,
int top,
int right,
int bottom,
int width,
int height,
unsigned char *ppu8Plane_y,
unsigned char *ppu8Plane_uv) {
if (!ppu8Plane_y || !ppu8Plane_uv) {
return;
}
if (!fix(left, top, right, bottom, width, height)) {
return;
}
int w = right - left;
for (int j = top;j <= bottom;j++) {
memset(ppu8Plane_y + left + j * width, 0, w);
memset(ppu8Plane_uv + left + j / 2 * width, 128, w);
}
}
测试:
#include
#include
#include
enum FILE_WRITE_MODE {
OVER_WRITE,
APPEND_WRITE
};
inline bool get_file_content(const char *path, std::string &str) {
std::ifstream ifs(path, std::ios::in);
if (!ifs || !ifs.good()) {
return false;
}
str.assign((std::istreambuf_iterator(ifs)), std::istreambuf_iterator());
ifs.close();
return !str.empty();
}
bool write_file_content(const char *path, const char *buf, size_t size, unsigned mode) {
if (!path || !buf) {
return false;
}
std::ofstream ofs;
switch (mode)
{
case OVER_WRITE:
ofs.open(path, std::ios::in | std::ios::trunc);
if (!ofs.is_open()) {
return false;
}
break;
case APPEND_WRITE:
ofs.open(path, std::ios::in | std::ios::app);
if (!ofs.is_open()) {
return false;
}
break;
default:
return false;
break;
}
ofs.write(buf, size);
ofs.close();
return true;
}
int main() {
std::string str;
if (get_file_content("./1653210331_1920x1080_56029_33_1920x1080.NV12", str)) {
size_t size = str.size();
std::cout << "load success! size:" << size << std::endl;
unsigned char *ppu8Plane0 = (unsigned char *)malloc(1920 * 1080 * 3 / 2);
unsigned char *ppu8Plane1 = ppu8Plane0 + 1920 * 1080;
memcpy(ppu8Plane0, str.c_str(), size);
blackening_nv12(0, 0, 1920 / 2 - 1, 1080 - 1, 1920, 1080, ppu8Plane0, ppu8Plane1);
size = 1920 * 1080 * 3 / 2;
if (write_file_content("./11_1920x1080.NV12", (char *)ppu8Plane0, size, OVER_WRITE)) {
std::cout << "rewrite success! size:" << size << std::endl;
}
}
return 0;
}