#include "drawTool.h" #include "lyn_plugin_dev.h" #include "freetype/freetype.h" #include <map> #include <mutex> #define CHECK_RETURN(cond, ret, log) if (cond) {/*LOG(ERROR) << log;*/ return ret;} struct YUVColor { uint8_t colorY; uint8_t colorU; uint8_t colorV; }; std::map<DrawColor, YUVColor> g_sampleColorMap = { {SAMPLE_DRAW_COLOR_WHITE, {180, 128, 128}}, {SAMPLE_DRAW_COLOR_BLACK, {16, 128, 128}}, {SAMPLE_DRAW_COLOR_RED, {65, 100, 212}}, {SAMPLE_DRAW_COLOR_GREEN, {112, 72, 58}}, {SAMPLE_DRAW_COLOR_BLUE, {35, 212, 114}}, {SAMPLE_DRAW_COLOR_YELLOW, {162, 44, 142}}, {SAMPLE_DARW_COLOR_CYAN, {131, 156, 44}} }; int PluginDrawBox(DrawBoxAttr *attr) { if (attr == nullptr || attr->imgData == nullptr) { return lynEPTR; } if (attr->startX > attr->imgW || attr->startY > attr->imgH || attr->boxW + attr->startX > attr->imgW || attr->boxH + attr->startY > attr->imgH) { LOG_PLUGIN_W("box point not in range, imgW %u imgH %u startX %u startY %u boxW %u boxH %u\n", attr->imgW, attr->imgH, attr->startX, attr->startY, attr->boxW, attr->boxH); return lynEINVARG; } attr->startX = (attr->startX / 2) * 2; attr->startY = (attr->startY / 2) * 2; attr->boxW = (attr->boxW / 2) * 2; attr->boxH = (attr->boxH / 2) * 2; if ((int)attr->boxW < 2 * attr->thickness || (int)attr->boxH < 2 * attr->thickness) { LOG_PLUGIN_W("box size less than twice of thickness, boxW %u boxH %u thickness %u\n", attr->boxW, attr->boxH, attr->thickness); return lynEINVARG; } if (attr->imgFmt != LYN_PIX_FMT_YUV420P && attr->imgFmt != LYN_PIX_FMT_NV12 && attr->imgFmt != LYN_PIX_FMT_NV21) { LOG_PLUGIN_W("format %d not support", attr->imgFmt); return lynEFORMAT; } unsigned char * dataY = attr->imgData; unsigned char * dataU = attr->imgData + attr->imgW * attr->imgH; unsigned char * dataV = attr->imgData + (attr->imgW * attr->imgH) * 5 / 4; unsigned char colorY = g_sampleColorMap[attr->color].colorY; unsigned char colorU = g_sampleColorMap[attr->color].colorU; unsigned char colorV = g_sampleColorMap[attr->color].colorV; for (int i = 0; i < attr->thickness; i++) { memset(dataY + attr->imgW * (attr->startY + i) + attr->startX, colorY, attr->boxW); memset(dataY + attr->imgW * (attr->startY + attr->boxH - attr->thickness + i) + attr->startX, colorY, attr->boxW); if (i % 2 != 0) { // uv 分量消减 continue; } if (attr->imgFmt == LYN_PIX_FMT_YUV420P) { memset(dataU + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorU, attr->boxW / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorV, attr->boxW / 2); memset(dataU + attr->imgW / 2 * ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX / 2, colorU, attr->boxW / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX / 2, colorV, attr->boxW / 2); } else if (attr->imgFmt == LYN_PIX_FMT_NV12) { unsigned char * colorTop = dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX; unsigned char * colorBottom = dataU + attr->imgW* ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX; for (uint32_t j = 0; j < attr->boxW / 2; j++) { *(colorTop + 2 * j) = colorU; *(colorTop + 2 * j + 1) = colorV; *(colorBottom + 2 * j) = colorU; *(colorBottom + 2 * j + 1) = colorV; } } else if (attr->imgFmt == LYN_PIX_FMT_NV21) { unsigned char * colorTop = dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX; unsigned char * colorBottom = dataU + attr->imgW* ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX; for (uint32_t j = 0; j < attr->boxW / 2; j++) { *(colorTop + 2 * j) = colorV; *(colorTop + 2 * j + 1) = colorU; *(colorBottom + 2 * j) = colorV; *(colorBottom + 2 * j + 1) = colorU; } } } for (int i = attr->thickness; i < (int)attr->boxH - attr->thickness; i++) { memset(dataY + attr->imgW * (attr->startY + i) + attr->startX, colorY, attr->thickness); memset(dataY + attr->imgW * (attr->startY + i) + attr->startX + attr->boxW - attr->thickness, colorY, attr->thickness); if (i % 2 != 0) { continue; } if (attr->imgFmt == LYN_PIX_FMT_YUV420P) { memset(dataU + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorU, attr->thickness / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorV, attr->thickness / 2); memset(dataU + attr->imgW / 2 * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) / 2, colorU, attr->thickness / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) / 2, colorV, attr->thickness / 2); } else if (attr->imgFmt == LYN_PIX_FMT_NV12) { for (int j = 0; j < attr->thickness / 2; j++) { *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j) = colorU; *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j + 1) = colorV; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j) = colorU; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j + 1) = colorV; } } else if (attr->imgFmt == LYN_PIX_FMT_NV21) { for (int j = 0; j < attr->thickness / 2; j++) { *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j) = colorV; *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j + 1) = colorU; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j) = colorV; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j + 1) = colorU; } } } return 0; } int PluginDrawCustomColorBox(CustomColorBoxAttr *attr) { if (attr == nullptr || attr->imgData == nullptr) { return lynEPTR; } if (attr->startX > attr->imgW || attr->startY > attr->imgH || attr->boxW + attr->startX > attr->imgW || attr->boxH + attr->startY > attr->imgH) { LOG_PLUGIN_W("box point not in range, imgW %u imgH %u startX %u startY %u boxW %u boxH %u\n", attr->imgW, attr->imgH, attr->startX, attr->startY, attr->boxW, attr->boxH); return lynEINVARG; } attr->startX = (attr->startX / 2) * 2; attr->startY = (attr->startY / 2) * 2; attr->boxW = (attr->boxW / 2) * 2; attr->boxH = (attr->boxH / 2) * 2; if ((int)attr->boxW < 2 * attr->thickness || (int)attr->boxH < 2 * attr->thickness) { LOG_PLUGIN_W("box size less than twice of thickness, boxW %u boxH %u thickness %u\n", attr->boxW, attr->boxH, attr->thickness); return lynEINVARG; } if (attr->imgFmt != LYN_PIX_FMT_YUV420P && attr->imgFmt != LYN_PIX_FMT_NV12 && attr->imgFmt != LYN_PIX_FMT_NV21) { LOG_PLUGIN_W("format %d not support", attr->imgFmt); return lynEFORMAT; } unsigned char * dataY = attr->imgData; unsigned char * dataU = attr->imgData + attr->imgW * attr->imgH; unsigned char * dataV = attr->imgData + (attr->imgW * attr->imgH) * 5 / 4; unsigned char colorY = attr->colorY; unsigned char colorU = attr->colorU; unsigned char colorV = attr->colorV; for (int i = 0; i < attr->thickness; i++) { memset(dataY + attr->imgW * (attr->startY + i) + attr->startX, colorY, attr->boxW); memset(dataY + attr->imgW * (attr->startY + attr->boxH - attr->thickness + i) + attr->startX, colorY, attr->boxW); if (i % 2 != 0) { // uv 分量消减 continue; } if (attr->imgFmt == LYN_PIX_FMT_YUV420P) { memset(dataU + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorU, attr->boxW / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorV, attr->boxW / 2); memset(dataU + attr->imgW / 2 * ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX / 2, colorU, attr->boxW / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX / 2, colorV, attr->boxW / 2); } else if (attr->imgFmt == LYN_PIX_FMT_NV12) { unsigned char * colorTop = dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX; unsigned char * colorBottom = dataU + attr->imgW* ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX; for (uint32_t j = 0; j < attr->boxW / 2; j++) { *(colorTop + 2 * j) = colorU; *(colorTop + 2 * j + 1) = colorV; *(colorBottom + 2 * j) = colorU; *(colorBottom + 2 * j + 1) = colorV; } } else if (attr->imgFmt == LYN_PIX_FMT_NV21) { unsigned char * colorTop = dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX; unsigned char * colorBottom = dataU + attr->imgW* ((attr->startY + attr->boxH - attr->thickness + i) / 2) + attr->startX; for (uint32_t j = 0; j < attr->boxW / 2; j++) { *(colorTop + 2 * j) = colorV; *(colorTop + 2 * j + 1) = colorU; *(colorBottom + 2 * j) = colorV; *(colorBottom + 2 * j + 1) = colorU; } } } for (int i = attr->thickness; i < (int)attr->boxH - attr->thickness; i++) { memset(dataY + attr->imgW * (attr->startY + i) + attr->startX, colorY, attr->thickness); memset(dataY + attr->imgW * (attr->startY + i) + attr->startX + attr->boxW - attr->thickness, colorY, attr->thickness); if (i % 2 != 0) { continue; } if (attr->imgFmt == LYN_PIX_FMT_YUV420P) { memset(dataU + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorU, attr->thickness / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + i) / 2) + attr->startX / 2, colorV, attr->thickness / 2); memset(dataU + attr->imgW / 2 * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) / 2, colorU, attr->thickness / 2); memset(dataV + attr->imgW / 2 * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) / 2, colorV, attr->thickness / 2); } else if (attr->imgFmt == LYN_PIX_FMT_NV12) { for (int j = 0; j < attr->thickness / 2; j++) { *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j) = colorU; *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j + 1) = colorV; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j) = colorU; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j + 1) = colorV; } } else if (attr->imgFmt == LYN_PIX_FMT_NV21) { for (int j = 0; j < attr->thickness / 2; j++) { *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j) = colorV; *(dataU + attr->imgW * ((attr->startY + i) / 2) + attr->startX + 2 * j + 1) = colorU; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j) = colorV; *(dataU + attr->imgW * ((attr->startY + i) / 2) + (attr->startX + attr->boxW - attr->thickness) + 2 * j + 1) = colorU; } } } return 0; } struct TextBitMap { uint8_t *buffer = nullptr; int w = 0; int h = 0; // char ch; wchar_t ch; FontSize fontSize; }; namespace sampleFreeType { static bool s_init = false; static int s_fontSize = 0; static std::mutex s_drawTextMux; static FT_Library ftLib; static FT_Face ftFace; static std::map<uint32_t, TextBitMap> s_textMap; int Init() { std::lock_guard<std::mutex> lock(s_drawTextMux); int ret = 0; if (s_init == false) { ret = FT_Init_FreeType(&ftLib); CHECK_RETURN(ret, lynEDRAWTEXT, "error ret " << ret); ret = FT_New_Face(ftLib, "/usr/share/Monaco_Linux.ttf", 0, &ftFace); CHECK_RETURN(ret, lynEDRAWTEXT, "error ret " << ret); ret = FT_Select_Charmap(ftFace, FT_ENCODING_UNICODE); CHECK_RETURN(ret, lynEDRAWTEXT, "error ret " << ret); s_init = true; } return ret; } TextBitMap* SelectSingleWchar(wchar_t ch, FontSize fontSize) { uint32_t key = ch; TextBitMap bitMap; key = (key << 8) + fontSize; std::lock_guard<std::mutex> lock(s_drawTextMux); if (s_fontSize != fontSize) { FT_Set_Char_Size(ftFace, 0, fontSize * 64, 0, 96); FT_Set_Pixel_Sizes(ftFace, 0, fontSize); s_fontSize = fontSize; } auto it = s_textMap.find(key); if (it == s_textMap.end()) { auto index = FT_Get_Char_Index(ftFace, ch); FT_Load_Glyph(ftFace, index, FT_LOAD_DEFAULT); FT_Render_Glyph(ftFace->glyph, FT_RENDER_MODE_NORMAL); bitMap.w = ftFace->glyph->bitmap.width; bitMap.h = ftFace->glyph->bitmap.rows; bitMap.buffer = (uint8_t *)malloc(bitMap.w * bitMap.h); bitMap.ch = ch; bitMap.fontSize = fontSize; // size += bitMap.w * bitMap.h; // printf("malloc total %d size %d font %d ch %c\n", size, bitMap.w * bitMap.h, bitMap.fontSize, bitMap.ch); memcpy(bitMap.buffer, ftFace->glyph->bitmap.buffer, bitMap.w * bitMap.h); s_textMap[key] = bitMap; } return &s_textMap[key]; } } // sampleFreeType inline void yuvSetdata(uint8_t *YBuff, uint8_t *UVBuff, lynPixelFormat_t yuvType, uint32_t width, uint32_t height, DarwPoint &drawPoint, uint8_t YColor, uint8_t UColor, uint8_t VColor, bool updateUV) { *(YBuff + drawPoint.y * width + drawPoint.x) = YColor; // update U V uint32_t u_offset = 0, v_offset = 0; // uint32_t plane_size = width * height / 4; switch (yuvType) { case LYN_PIX_FMT_NV12: { u_offset = (drawPoint.y / 2) * width + drawPoint.x / 2 * 2; *(UVBuff + u_offset) = UColor; *(UVBuff + u_offset + 1) = VColor; return; } break; case LYN_PIX_FMT_NV21: { v_offset = (drawPoint.y / 2) * width + drawPoint.x / 2 * 2; u_offset = v_offset + 1; } break; case LYN_PIX_FMT_YUV420P: { u_offset = drawPoint.y / 2 * width / 2 + drawPoint.x / 2; v_offset = u_offset + width * height / 4; } break; default: { return ; } } UVBuff[u_offset] = UColor; UVBuff[v_offset] = VColor; } int PluginDrawTextV2(DrawTextAttrV2 *attr) { if (attr == nullptr || attr->imgData == nullptr || attr->text == nullptr) { return lynEPTR; } if (attr->imgFmt != LYN_PIX_FMT_YUV420P && attr->imgFmt != LYN_PIX_FMT_NV12 && attr->imgFmt != LYN_PIX_FMT_NV21) { LOG_PLUGIN_W("format %d not support\n", attr->imgFmt); return lynEFORMAT; } int ret = 0; ret = sampleFreeType::Init(); if (ret != 0) { return ret; } unsigned char * data_y = attr->imgData; unsigned char * data_u = attr->imgData + attr->imgW * attr->imgH; // unsigned char * data_v = attr->imgData + (attr->imgW * attr->imgH) * 5 / 4; uint32_t startX = attr->startX; uint32_t startY = attr->startY; // uint32_t imgW = attr->imgW; uint32_t imgH = attr->imgH; int char_num = 0; uint32_t pix_x_base = startX; uint32_t pix_y_base = startY; uint8_t colorY = g_sampleColorMap[attr->color].colorY; uint8_t colorU = g_sampleColorMap[attr->color].colorU; uint8_t colorV = g_sampleColorMap[attr->color].colorV; uint8_t letterSpace = (attr->fontSize / SAMPLE_FONT_SIZE_18 < 2) ? 2 : attr->fontSize / SAMPLE_FONT_SIZE_18; for (wchar_t ch = *(attr->text + char_num); *(attr->text + char_num) != '\0'; char_num++) { ch = *(attr->text + char_num); if (ch == ' ') { pix_x_base += attr->fontSize / 2 + 2; continue; } auto bitMap = sampleFreeType::SelectSingleWchar(ch, attr->fontSize); int w = bitMap->w; int h = bitMap->h; pix_y_base = startY - h; unsigned char * data = bitMap->buffer; for (int j = 0; j < h; j++) { for (int i = 0; i < w; i++) { uint32_t pix_x = pix_x_base + i; uint32_t pix_y = pix_y_base + j; if (pix_y < 0 || pix_y >= imgH || pix_x >= attr->imgW || pix_x < 0) { continue; } if (data[j * w + i] != 0) { DarwPoint draw_point; draw_point.x = pix_x; draw_point.y = pix_y; yuvSetdata(data_y, data_u, attr->imgFmt, attr->imgW, attr->imgH, draw_point, colorY, colorU, colorV, true); } } } pix_x_base += w + letterSpace ; } return 0; } int PluginDrawText(DrawTextAttr *attr) { if (attr == nullptr || attr->imgData == nullptr || attr->text == nullptr) { return lynEPTR; } wchar_t wText[100]; auto len = std::mbstowcs(wText, attr->text, 100); if (len < 0) { return -1; } DrawTextAttrV2 attrV2; attrV2.fontSize = attr->fontSize; attrV2.imgData = attr->imgData; attrV2.imgFmt = attr->imgFmt; attrV2.imgH = attr->imgH; attrV2.imgW = attr->imgW; attrV2.startX = attr->startX; attrV2.startY = attr->startY; attrV2.text = wText; attrV2.color = SAMPLE_DRAW_COLOR_WHITE; return PluginDrawTextV2(&attrV2); } /** * @brief 画 y1 = y2 的横直线 * * @param[] attr * @return int */ int DrawTransverseLine(DrawLineAttr *attr) { int ret = 0; uint8_t *YBuff = attr->imgData; uint8_t *UVBuff = attr->imgData + attr->imgW * attr->imgH; unsigned char colorY = g_sampleColorMap[attr->color].colorY; unsigned char colorU = g_sampleColorMap[attr->color].colorU; unsigned char colorV = g_sampleColorMap[attr->color].colorV; uint32_t x0 = 0, x1 = 0; uint32_t y = attr->startPoint.y; if (attr->startPoint.x < attr->endPoint.x) { x0 = attr->startPoint.x; x1 = attr->endPoint.x; } else { x0 = attr->endPoint.x; x1 = attr->startPoint.x; } uint32_t length = x1 - x0; for (int i = 0; i < attr->thickness; i++) { memset(YBuff + attr->imgW * (y + i) + x0, colorY, length); if (i % 2 != 0) { // uv 分量消减 continue; } if (attr->imgFmt == LYN_PIX_FMT_YUV420P) { unsigned char *dataU = attr->imgData + attr->imgW * attr->imgH; unsigned char *dataV = attr->imgData + (attr->imgW * attr->imgH) * 5 / 4; memset(dataU + attr->imgW / 2 * ((y + i) / 2) + x0 / 2, colorU, length / 2); memset(dataV + attr->imgW / 2 * ((y + i) / 2) + x0 / 2, colorV, length / 2); } else if (attr->imgFmt == LYN_PIX_FMT_NV12) { unsigned char *colorTop = UVBuff + attr->imgW * ((y + i) / 2) + x0; for (uint32_t j = 0; j < length / 2; j++) { *(colorTop + 2 * j) = colorU; *(colorTop + 2 * j + 1) = colorV; } } else if (attr->imgFmt == LYN_PIX_FMT_NV21) { unsigned char *colorTop = UVBuff + attr->imgW * ((y + i) / 2) + x0; for (uint32_t j = 0; j < length / 2; j++) { *(colorTop + 2 * j) = colorV; *(colorTop + 2 * j + 1) = colorU; } } } return ret; } int PluginDrawLine(DrawLineAttr *attr) { if (attr == nullptr || attr->imgData == nullptr) { return lynEPTR; } if (attr->startPoint.x > attr->imgW || attr->startPoint.y > attr->imgH || attr->endPoint.x > attr->imgW || attr->endPoint.y > attr->imgH) { LOG_PLUGIN_W("point not in range, imgW %u imgH %u startX %u startY %u endX %u endY %u\n", attr->imgW, attr->imgH, attr->startPoint.x, attr->startPoint.y, attr->endPoint.x, attr->endPoint.y); return lynEINVARG; } if (attr->imgFmt != LYN_PIX_FMT_YUV420P && attr->imgFmt != LYN_PIX_FMT_NV12 && attr->imgFmt != LYN_PIX_FMT_NV21) { LOG_PLUGIN_W("format %d not support", attr->imgFmt); return lynEFORMAT; } if (attr->startPoint.y == attr->endPoint.y) { return DrawTransverseLine(attr); } int ret = 0; uint8_t *YBuff = attr->imgData; uint8_t *UVBuff = attr->imgData + attr->imgW * attr->imgH; // uint16_t i = 0; uint8_t colorY = g_sampleColorMap[attr->color].colorY; uint8_t colorU = g_sampleColorMap[attr->color].colorU; uint8_t colorV = g_sampleColorMap[attr->color].colorV; // uint32_t halfWidth = attr->imgW / 2; for (uint16_t i = 0; i < attr->thickness; i++) { uint16_t x0 = attr->startPoint.x, y0 = attr->startPoint.y; uint16_t x1 = attr->endPoint.x, y1 = attr->endPoint.y; x0 = (x0 >= attr->imgW) ? (x0 - attr->thickness) : x0; x1 = (x1 >= attr->imgW) ? (x1 - attr->thickness) : x1; y0 = (y0 >= attr->imgH) ? (y0 - attr->thickness) : y0; y1 = (y1 >= attr->imgH) ? (y1 - attr->thickness) : y1; uint16_t dx = (x0 > x1) ? (x0 - x1) : (x1 - x0); uint16_t dy = (y0 > y1) ? (y0 - y1) : (y1 - y0); if (dx <= dy) { x0 += i; x1 += i; } else { y0 += i; y1 += i; } int xstep = (x0 < x1) ? 1 : -1; int ystep = (y0 < y1) ? 1 : -1; int nstep = 0, eps = 0; DarwPoint draw_point; draw_point.x = x0; draw_point.y = y0; // bool updateUV = i == attr->thickness ? false : true; bool updateUV = true; // 布雷森汉姆算法画线 if (dx > dy) { while (nstep <= dx) { yuvSetdata(YBuff, UVBuff, attr->imgFmt, attr->imgW, attr->imgH, draw_point, colorY, colorU, colorV, updateUV); eps += dy; if ((eps << 1) >= dx) { draw_point.y += ystep; eps -= dx; } draw_point.x += xstep; nstep++; } } else { while (nstep <= dy) { yuvSetdata(YBuff, UVBuff, attr->imgFmt, attr->imgW, attr->imgH, draw_point, colorY, colorU, colorV, updateUV); eps += dx; if ((eps << 1) >= dy) { draw_point.x += xstep; eps -= dy; } draw_point.y += ystep; nstep++; } } } return ret; } int lynDrawBoxAndText(lynDrawBoxAndTextPara *para) { int ret = 0; uint8_t *imgData = (uint8_t *)lynPluginGetVirtAddr(para->imgData); lynBoxesInfo *boxesInfo = (lynBoxesInfo *)lynPluginGetVirtAddr(para->boxesInfo); for (uint32_t i = 0; i < boxesInfo->boxesNum; i++) { auto& box = boxesInfo->boxes[i]; DrawColor boxColor = (box.alarm == 1) ? SAMPLE_DRAW_COLOR_RED : SAMPLE_DRAW_COLOR_BLUE; DrawBoxAttr boxAttr = {box.xmin, box.ymin, box.xmax - box.xmin, box.ymax - box.ymin, para->imgW, para->imgH, SAMPLE_DRAW_THICK_2, boxColor, para->imgFmt, imgData}; ret = PluginDrawBox(&boxAttr); if (ret != 0) { break; } DrawTextAttrV2 textAttr = {box.xmin, box.ymin, para->imgW, para->imgH, para->imgFmt, SAMPLE_FONT_SIZE_24, boxColor, imgData, box.lable}; ret = PluginDrawTextV2(&textAttr); if (ret != 0) { break; } } return ret; }