From c42c0352baa2c0393447419fbc7e6aacd57503c1 Mon Sep 17 00:00:00 2001 From: BlueMatthew Date: Mon, 12 Feb 2024 23:33:44 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96OSD=E6=96=87=E5=AD=97?= =?UTF-8?q?=E6=8F=8F=E8=BE=B9=E7=9A=84=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/cpp/CvText.cpp | 32 +++++++-- app/src/main/cpp/CvText.h | 6 +- app/src/main/cpp/PhoneDevice.cpp | 71 +++++++++++-------- .../java/com/xypower/mpapp/MainActivity.java | 2 +- gradle.properties | 4 +- 5 files changed, 74 insertions(+), 41 deletions(-) diff --git a/app/src/main/cpp/CvText.cpp b/app/src/main/cpp/CvText.cpp index e0d2f56e..d1c0c7e9 100644 --- a/app/src/main/cpp/CvText.cpp +++ b/app/src/main/cpp/CvText.cpp @@ -99,7 +99,7 @@ namespace cv { void putText( InputOutputArray img, const String& text, Point org, int fontHeight, Scalar color, - int thickness, int line_type, bool bottomLeftOrigin + int thickness, int line_type, bool bottomLeftOrigin, bool usingStroker ); Size getTextSize(const String& text, int fontHeight, int thickness, CV_OUT int* baseLine); @@ -241,7 +241,7 @@ namespace cv { void FreeType2Impl::putText( InputOutputArray _img, const String& _text, Point _org, int _fontHeight, Scalar _color, - int _thickness, int _line_type, bool _bottomLeftOrigin + int _thickness, int _line_type, bool _bottomLeftOrigin, bool usingStroker ) { CV_Assert(mIsFaceAvailable == true); @@ -279,8 +279,14 @@ namespace cv { } } else { - // putTextOutline(_img, _text, _org, _fontHeight, _color, _thickness, _line_type, _bottomLeftOrigin); - putTextStroker(_img, _text, _org, _fontHeight, _color, _thickness, _line_type, _bottomLeftOrigin); + if (usingStroker) + { + putTextStroker(_img, _text, _org, _fontHeight, _color, _thickness, _line_type, _bottomLeftOrigin); + } + else + { + putTextOutline(_img, _text, _org, _fontHeight, _color, _thickness, _line_type, _bottomLeftOrigin); + } } } @@ -302,6 +308,7 @@ namespace cv { hb_buffer_get_glyph_infos(hb_buffer, &textLen); CV_Assert(info != NULL); #else + std::wstring_convert> converter; wstring wstr = converter.from_bytes(_text); #endif @@ -327,6 +334,7 @@ namespace cv { CV_Assert(!FT_Load_Glyph(mFace, info[i].codepoint, 0)); #else for (unsigned int i = 0; i < wstr.size(); i++) { + wchar_t ch = wstr[i]; CV_Assert(!FT_Load_Glyph(mFace, FT_Get_Char_Index(mFace, wstr[i]), 0)); #endif FT_GlyphSlot slot = mFace->glyph; @@ -408,8 +416,9 @@ namespace cv { bbox.xMax = bbox.yMax = -32000; // Get some metrics of our image. - // int imgWidth = mat.cols; + int imgWidth = mat.cols; + // _color. cv::Vec3b outlineColor = cv::Vec3b(255 - (uchar)_color[0], 255 - (uchar)_color[1], 255 - (uchar)_color[2]); cv::Vec3b fontColor = cv::Vec3b((uchar)_color[0], (uchar)_color[1], (uchar)_color[2]); @@ -540,9 +549,14 @@ namespace cv { // int row = (imgHeight - 1 - (s->y - rect.ymin)) - imgHeight + (rect.ymax - rect.ymin); // int row = (imgHeight - 1 - (s->y - rect.ymin)); int row = (bbox.yMax - bbox.yMin) - (s->y - rect.ymin) + _org.y - offsetY; + int col = s->x - rect.xmin + w + _org.x + bearingX; + if (row < 0 || col < 0 || row >= imgHeight || col >= imgWidth) + { + continue; + } // int row = ((bbox.yMax - bbox.yMin) - (glyph_bbox.yMax - glyph_bbox.yMin)) / 2 - (s->y - rect.ymin) + _org.y; // mat.at((imgHeight - 1 - (s->y - rect.ymin)), s->x - rect.xmin + w) = outlineColor; - mat.at(row, s->x - rect.xmin + w + _org.x + bearingX) = outlineColor; + mat.at(row, col) = outlineColor; // mat.at(-(s->y - rect.ymin), s->x - rect.xmin + w) = outlineColor; // vec3b. /* @@ -562,6 +576,11 @@ namespace cv { { // int row = (imgHeight - 1 - (s->y - rect.ymin)) - imgHeight + (rect.ymax - rect.ymin); int row = (bbox.yMax - bbox.yMin) - (s->y - rect.ymin) + _org.y - offsetY; + int col = s->x - rect.xmin + w + _org.x + bearingX; + if (row < 0 || col < 0 || row >= imgHeight || col >= imgWidth) + { + continue; + } // int row = ((bbox.yMax - bbox.yMin) - (glyph_bbox.yMax - glyph_bbox.yMin)) / 2 - (s->y - rect.ymin) + _org.y; mat.at(row, s->x - rect.xmin + w + _org.x + bearingX) = fontColor; // mat.at(-(s->y - rect.ymin), s->x - rect.xmin + w) = fontColor; @@ -913,6 +932,7 @@ namespace cv { CV_Assert(!FT_Set_Pixel_Sizes(mFace, _fontHeight, _fontHeight)); FT_Vector currentPos = { 0,0 }; + FT_Set_Transform(mFace, 0, ¤tPos); #if defined(USING_HB) hb_buffer_t *hb_buffer = hb_buffer_create(); CV_Assert(hb_buffer != NULL); diff --git a/app/src/main/cpp/CvText.h b/app/src/main/cpp/CvText.h index 452300e2..d19ca56b 100644 --- a/app/src/main/cpp/CvText.h +++ b/app/src/main/cpp/CvText.h @@ -52,8 +52,12 @@ namespace cv { @param line_type Line type. See the line for details. @param bottomLeftOrigin When true, the image data origin is at the bottom-left corner. Otherwise, it is at the top-left corner. */ + virtual void putText(InputOutputArray img, const String& text, Point org, int fontHeight, Scalar color, int thickness, int line_type, bool bottomLeftOrigin) + { + putText(img, text, org, fontHeight, color, thickness, line_type, bottomLeftOrigin, false); + } - virtual void putText(InputOutputArray img, const String& text, Point org, int fontHeight, Scalar color, int thickness, int line_type, bool bottomLeftOrigin) = 0; + virtual void putText(InputOutputArray img, const String& text, Point org, int fontHeight, Scalar color, int thickness, int line_type, bool bottomLeftOrigin, bool usingStroker) = 0; /** @brief Calculates the width and height of a text string. diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index d22bf617..33f5baad 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -941,10 +941,10 @@ void DrawOutlineText(cv::Ptr ft2, cv::Mat& mat, const std::st textSize = ft2->getTextSize(*it, fontSize, thickness, &baseline); lineHeight = std::max(lineHeight, textSize.height); - ft2->putText(mat, *it, pt, fontSize, clr, thickness, cv::LINE_AA, false); + ft2->putText(mat, *it, pt, fontSize, clr, thickness, cv::LINE_AA, false, true); pt.x = startPoint.x; - pt.y += lineHeight > 0 ? (lineHeight + 2) : 0; + pt.y += lineHeight > 0 ? (lineHeight + fontSize / 5) : 0; } } @@ -958,13 +958,11 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) mPhotoInfo.photoTime = time(NULL); int baseline = 0; - cv::Size textSize, textSize2; - double fontScale = 1; // base 1024 + cv::Size textSize; double height = mat.size().height; double width = mat.size().width; // double ratio = std::min(height / 1024, width / 1920); - double ratio = std::sqrt((height * width) / (1024.0 * 1920.0)); - fontScale = fontScale * ratio; + double ratio = height / 1024.0; // cv::Rect rc(0, 0, mat.cols, mat.rows); // cv::rectangle (mat, rc, cv::Scalar(255, 255, 255), cv::FILLED); @@ -1023,13 +1021,25 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) } } - int thickness = 4 * ratio; + int thickness = (int)(4.0 * ratio); if (thickness < 2) thickness = 2; cv::Scalar scalar(255, 255, 255); // white - int fontSize = 24; - std::string fontPath = m_appPath+ "fonts/Noto.ttf"; + int fontSize = (int)(24.0 * ratio); + std::string fontPath; + if (existsFile("/system/fonts/NotoSansCJK-Regular.ttc")) + { + fontPath = "/system/fonts/NotoSansCJK-Regular.ttc"; + } + else if (existsFile("/system/fonts/NotoSerifCJK-Regular.ttc")) + { + fontPath = "/system/fonts/NotoSerifCJK-Regular.ttc"; + } + else + { + fontPath = m_appPath+ "fonts/Noto.otf"; + } cv::Ptr ft2; ft2 = cv::ft::createFreeType2(); ft2->loadFontData(fontPath.c_str(), 0); @@ -1040,7 +1050,7 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) NdkCamera::CAPTURE_RESULT captureResult = mCamera->getCaptureResult(); char str[128] = { 0 }; - snprintf(str, sizeof(str), "AE=%u EXPS=%ums ISO=%d AF=%u FD=%.3f AFS=%u HDR=%d", captureResult.autoExposure, + snprintf(str, sizeof(str), "通道 AE=%u EXPS=%ums ISO=%d AF=%u FD=%.3f AFS=%u HDR=%d", captureResult.autoExposure, (unsigned int)(captureResult.exposureTime / 1000000), captureResult.sensitibity, captureResult.autoFocus, @@ -1050,8 +1060,8 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) // cv::putText(mat, str, cv::Point(0, mat.rows - 20), cv::FONT_HERSHEY_COMPLEX, fontScale, scalar, thickness1, cv::LINE_AA); - ft2->putText(mat, str, cv::Point(0, mat.rows - 48), - fontSize, scalarRed, thickness, cv::LINE_AA, false); + ft2->putText(mat, str, cv::Point(0, mat.rows - fontSize - 20), + fontSize, scalarRed, -1, cv::LINE_AA, false); // text.putText(mat, str.c_str(), cv::Point(0, mat.rows - 20), scalar); @@ -1062,7 +1072,7 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) #endif - cv::Point pt1, pt2; + cv::Point pt; for (vector::const_iterator it = mOsds.cbegin(); it != mOsds.cend(); ++it) { if (it->text.empty()) @@ -1070,38 +1080,37 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) continue; } +#ifdef _DEBUG + if (it->alignment == OSD_ALIGNMENT_BOTTOM_RIGHT) + { + int aa = 0; + } +#endif + textSize = ft2->getTextSize(it->text, fontSize, thickness, &baseline); + XYLOG(XYLOG_SEVERITY_DEBUG, "%s font Size=%d height: %d baseline=%d", it->text.c_str(), fontSize, textSize.height, baseline); if (it->alignment == OSD_ALIGNMENT_TOP_LEFT) { - pt1.x = it->x * ratio; - pt1.y = it->y * ratio + textSize.height; + pt.x = it->x * ratio; + pt.y = it->y * ratio; } else if (it->alignment == OSD_ALIGNMENT_TOP_RIGHT) { - pt1.x = width - textSize.width - it->x * ratio; - pt1.y= it->y * ratio + textSize.height; + pt.x = width - textSize.width - it->x * ratio; + pt.y= it->y * ratio; } else if (it->alignment == OSD_ALIGNMENT_BOTTOM_RIGHT) { - pt1.x = width - textSize.width - it->x * ratio; - pt1.y = height - it->y * ratio; + pt.x = width - textSize.width - it->x * ratio; + pt.y = height - it->y * ratio - textSize.height; } else if (it->alignment == OSD_ALIGNMENT_BOTTOM_LEFT) { - pt1.x = it->x * ratio; - pt1.y = height - it->y * ratio; + pt.x = it->x * ratio; + pt.y = height - it->y * ratio - textSize.height; } - - cv::Point pt = pt1; - pt.x += textSize.width; - pt.y -= textSize.height; - - // cv::rectangle(mat, pt1, pt, scalar2, -1); - pt2 = pt1; - pt2.y += textSize.height; - - DrawOutlineText(ft2, mat, it->text, pt1, fontScale, scalar, thickness); + DrawOutlineText(ft2, mat, it->text, pt, fontSize, scalar, thickness); } vector params; diff --git a/app/src/main/java/com/xypower/mpapp/MainActivity.java b/app/src/main/java/com/xypower/mpapp/MainActivity.java index d9294268..c44d3b35 100644 --- a/app/src/main/java/com/xypower/mpapp/MainActivity.java +++ b/app/src/main/java/com/xypower/mpapp/MainActivity.java @@ -227,7 +227,7 @@ public class MainActivity extends AppCompatActivity { } if (needRequire) { ActivityCompat.requestPermissions(MainActivity.this, accessPermissions, MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE); - return; + // return; } binding.logs.setText(""); diff --git a/gradle.properties b/gradle.properties index 7348c21c..88553c68 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,9 +18,9 @@ android.nonTransitiveRClass=true android.useAndroidX=true android.enableJetifier=true -# opencvsdk=D:/Workspace/deps/opencv-mobile-4.8.0-android +opencvsdk=D:/Workspace/deps/opencv-mobile-4.9.0-android coreroot=D:/Workspace/Github/xymp/Core -opencvsdk=D:/Workspace/deps/opencv-v5 +# opencvsdk=D:/Workspace/deps/opencv-v5 asioroot=D:/Workspace/deps/asio-1.28.0 evpproot=D:/Workspace/Github/evpp ncnnroot=D:/Workspace/deps/ncnn-20230517-android-vulkan