From 19d0f90042e240ea6fcd50bdafad320e8deb7d48 Mon Sep 17 00:00:00 2001 From: huangji731 Date: Tue, 11 Jun 2024 10:29:50 +0800 Subject: [PATCH] https://gitee.com/openharmony/window_window_manager/issues/I9W473 Signed-off-by: huangji731 --- snapshot/include/snapshot_utils.h | 17 ++-- snapshot/src/snapshot_display.cpp | 65 +++++++++------- snapshot/src/snapshot_utils.cpp | 77 ++++++++++--------- .../test/unittest/snapshot_display_test.cpp | 34 +++++++- 4 files changed, 119 insertions(+), 74 deletions(-) diff --git a/snapshot/include/snapshot_utils.h b/snapshot/include/snapshot_utils.h index 5b617d896f..f1936fb74f 100644 --- a/snapshot/include/snapshot_utils.h +++ b/snapshot/include/snapshot_utils.h @@ -33,14 +33,15 @@ struct WriteToJpegParam { const uint8_t *data; }; -struct CmdArgments { - bool isDisplayIdSet = false; +struct CmdArguments { Rosen::DisplayId displayId = Rosen::DISPLAY_ID_INVALID; std::string fileName; - bool isWidthSet = false; + std::string fileType; int32_t width = -1; - bool isHeightSet = false; int32_t height = -1; + bool isDisplayIdSet = false; + bool isWidthSet = false; + bool isHeightSet = false; }; class SnapShotUtils { @@ -49,8 +50,8 @@ public: ~SnapShotUtils() = default; static void PrintUsage(const std::string &cmdLine); - static bool CheckFileNameValid(const std::string &fileName); - static std::string GenerateFileName(int offset = 0); + static bool CheckFileNameValid(const std::string &fileName, std::string fileType = "jpeg"); + static std::string GenerateFileName(std::string fileType, int offset = 0); static bool CheckWidthAndHeightValid(int32_t w, int32_t h); static bool RGBA8888ToRGB888(const uint8_t* rgba8888Buf, uint8_t *rgb888Buf, int32_t size); static bool RGB565ToRGB888(const uint8_t* rgb565Buf, uint8_t *rgb888Buf, int32_t size); @@ -59,10 +60,10 @@ public: static bool WriteToJpeg(int fd, const WriteToJpegParam ¶m); static bool WriteToJpegWithPixelMap(const std::string &fileName, Media::PixelMap &pixelMap); static bool WriteToJpegWithPixelMap(int fd, Media::PixelMap &pixelMap); - static bool ProcessArgs(int argc, char * const argv[], CmdArgments& cmdArgments); + static bool ProcessArgs(int argc, char * const argv[], CmdArguments& cmdArgments); static bool CheckWHValid(int32_t param); static bool CheckParamValid(const WriteToJpegParam ¶m); - static bool SaveSnapShot(const std::string &filename, Media::PixelMap &pixelMap); + static bool SaveSnapShot(const std::string &filename, Media::PixelMap &pixelMap, std::string fileType = "jpeg"); private: static bool ProcessDisplayId(Rosen::DisplayId &displayId, bool isDisplayIdSet); }; diff --git a/snapshot/src/snapshot_display.cpp b/snapshot/src/snapshot_display.cpp index ba0c0bac55..62f9d705f4 100644 --- a/snapshot/src/snapshot_display.cpp +++ b/snapshot/src/snapshot_display.cpp @@ -35,15 +35,15 @@ static const std::string DEVELOPER_MODE_STATE_ON_DEFAULT = "false"; static const std::string DEVELOPER_MODE_PARAMETER = "const.security.developermode.state"; static const std::string IS_DEVELOPER_MODE = GetParameter(DEVELOPER_MODE_PARAMETER, DEVELOPER_MODE_STATE_ON_DEFAULT); -static bool GetScreenshotByCmdArgments(CmdArgments& cmdArgments, sptr display, +static bool GetScreenshotByCmdArguments(CmdArguments& cmdArguments, sptr display, std::shared_ptr& pixelMap); int main(int argc, char *argv[]) { - CmdArgments cmdArgments; - cmdArgments.fileName = ""; + CmdArguments cmdArguments; + cmdArguments.fileName = ""; - if (!SnapShotUtils::ProcessArgs(argc, argv, cmdArgments)) { + if (!SnapShotUtils::ProcessArgs(argc, argv, cmdArguments)) { return 0; } @@ -52,60 +52,67 @@ int main(int argc, char *argv[]) return 0; } - auto display = DisplayManager::GetInstance().GetDisplayById(cmdArgments.displayId); + auto display = DisplayManager::GetInstance().GetDisplayById(cmdArguments.displayId); if (display == nullptr) { - std::cout << "error: GetDisplayById " << cmdArgments.displayId << " error!" << std::endl; + std::cout << "error: GetDisplayById " << cmdArguments.displayId << " error!" << std::endl; return -1; } + if (cmdArguments.fileType != "png") { + cmdArguments.fileType = "jpeg"; + } - std::cout << "process: display " << cmdArgments.displayId << - ": width " << display->GetWidth() << ", height " << display->GetHeight() << std::endl; + std::cout << "process: display " << cmdArguments.displayId << ", file type: " << cmdArguments.fileType << + ", width: " << display->GetWidth() << ", height: " << display->GetHeight() << std::endl; // get PixelMap from DisplayManager API std::shared_ptr pixelMap = nullptr; - if (!GetScreenshotByCmdArgments(cmdArgments, display, pixelMap)) { + if (!GetScreenshotByCmdArguments(cmdArguments, display, pixelMap)) { return -1; } bool ret = false; if (pixelMap != nullptr) { - ret = SnapShotUtils::WriteToJpegWithPixelMap(cmdArgments.fileName, *pixelMap); + if (cmdArguments.fileType == "png") { + ret = SnapShotUtils::SaveSnapShot(cmdArguments.fileName, *pixelMap, cmdArguments.fileType); + } else { + ret = SnapShotUtils::WriteToJpegWithPixelMap(cmdArguments.fileName, *pixelMap); + } } if (!ret) { - std::cout << "\nerror: snapshot display " << cmdArgments.displayId << - ", write to " << cmdArgments.fileName << " as jpeg failed!" << std::endl; + std::cout << "\nerror: snapshot display " << cmdArguments.displayId << + ", write to " << cmdArguments.fileName << " as jpeg failed!" << std::endl; return -1; } - std::cout << "\nsuccess: snapshot display " << cmdArgments.displayId << " , write to " << - cmdArgments.fileName << " as jpeg, width " << pixelMap->GetWidth() << - ", height " << pixelMap->GetHeight() << std::endl; + std::cout << "\nsuccess: snapshot display " << cmdArguments.displayId << " , write to " << + cmdArguments.fileName << " as " << cmdArguments.fileType << ", width: " << pixelMap->GetWidth() << + ", height: " << pixelMap->GetHeight() << std::endl; _exit(0); } -static bool GetScreenshotByCmdArgments(CmdArgments& cmdArgments, sptr display, +static bool GetScreenshotByCmdArguments(CmdArguments& cmdArguments, sptr display, std::shared_ptr& pixelMap) { - if (!cmdArgments.isWidthSet && !cmdArgments.isHeightSet) { - pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArgments.displayId); // default width & height + if (!cmdArguments.isWidthSet && !cmdArguments.isHeightSet) { + pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArguments.displayId); // default width & height } else { - if (!cmdArgments.isWidthSet) { - cmdArgments.width = display->GetWidth(); - std::cout << "process: reset to display's width " << cmdArgments.width << std::endl; + if (!cmdArguments.isWidthSet) { + cmdArguments.width = display->GetWidth(); + std::cout << "process: reset to display's width " << cmdArguments.width << std::endl; } - if (!cmdArgments.isHeightSet) { - cmdArgments.height = display->GetHeight(); - std::cout << "process: reset to display's height " << cmdArgments.height << std::endl; + if (!cmdArguments.isHeightSet) { + cmdArguments.height = display->GetHeight(); + std::cout << "process: reset to display's height " << cmdArguments.height << std::endl; } - if (!SnapShotUtils::CheckWidthAndHeightValid(cmdArgments.width, cmdArgments.height)) { - std::cout << "error: width " << cmdArgments.width << " height " << - cmdArgments.height << " invalid!" << std::endl; + if (!SnapShotUtils::CheckWidthAndHeightValid(cmdArguments.width, cmdArguments.height)) { + std::cout << "error: width " << cmdArguments.width << " height " << + cmdArguments.height << " invalid!" << std::endl; return false; } const Media::Rect rect = {0, 0, display->GetWidth(), display->GetHeight()}; - const Media::Size size = {cmdArgments.width, cmdArgments.height}; + const Media::Size size = {cmdArguments.width, cmdArguments.height}; constexpr int rotation = 0; - pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArgments.displayId, rect, size, rotation); + pixelMap = DisplayManager::GetInstance().GetScreenshot(cmdArguments.displayId, rect, size, rotation); } return true; } \ No newline at end of file diff --git a/snapshot/src/snapshot_utils.cpp b/snapshot/src/snapshot_utils.cpp index 4ec69531a7..e9a1c72e4b 100644 --- a/snapshot/src/snapshot_utils.cpp +++ b/snapshot/src/snapshot_utils.cpp @@ -12,6 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "snapshot_utils.h" #include #include @@ -29,7 +30,6 @@ #include #include -#include "snapshot_utils.h" #include "image_packer.h" #include "jpeglib.h" @@ -45,7 +45,7 @@ constexpr uint8_t B_INDEX = 0; constexpr uint8_t G_INDEX = 1; constexpr uint8_t R_INDEX = 2; constexpr uint8_t SHIFT_2_BIT = 2; -constexpr uint8_t SHITF_3_BIT = 3; +constexpr uint8_t SHIFT_3_BIT = 3; constexpr uint8_t SHIFT_5_BIT = 5; constexpr uint8_t SHIFT_8_BIT = 8; constexpr uint8_t SHIFT_11_BIT = 11; @@ -58,6 +58,7 @@ constexpr uint32_t RGBA8888_MASK_BLUE = 0x000000FF; constexpr uint32_t RGBA8888_MASK_GREEN = 0x0000FF00; constexpr uint32_t RGBA8888_MASK_RED = 0x00FF0000; +constexpr uint8_t PNG_PACKER_QUALITY = 100; constexpr uint8_t PACKER_QUALITY = 75; constexpr uint32_t PACKER_SUCCESS = 0; struct MissionErrorMgr : public jpeg_error_mgr { @@ -70,21 +71,22 @@ void mission_error_exit(j_common_ptr cinfo) std::cout << __func__ << ": param is invalid." << std::endl; return; } - auto err = (MissionErrorMgr*)cinfo->err; + auto err = reinterpret_cast(cinfo->err); longjmp(err->environment, 1); } const char *VALID_SNAPSHOT_PATH = "/data/local/tmp"; const char *DEFAULT_SNAPSHOT_PREFIX = "/snapshot"; const char *VALID_SNAPSHOT_SUFFIX = ".jpeg"; +const char *VALID_SNAPSHOT_PNG_SUFFIX = ".png"; void SnapShotUtils::PrintUsage(const std::string &cmdLine) { std::cout << "usage: " << cmdLine.c_str() << - " [-i displayId] [-f output_file] [-w width] [-h height] [-m]" << std::endl; + " [-i displayId] [-f output_file] [-w width] [-h height] [-t type] [-m]" << std::endl; } -std::string SnapShotUtils::GenerateFileName(int offset) +std::string SnapShotUtils::GenerateFileName(std::string fileType, int offset) { timeval tv; std::string fileName = VALID_SNAPSHOT_PATH; @@ -102,13 +104,15 @@ std::string SnapShotUtils::GenerateFileName(int offset) fileName += timeStr; } } - fileName += VALID_SNAPSHOT_SUFFIX; + fileName += (fileType == "png") ? VALID_SNAPSHOT_PNG_SUFFIX : VALID_SNAPSHOT_SUFFIX; return fileName; } -bool SnapShotUtils::CheckFileNameValid(const std::string &fileName) +bool SnapShotUtils::CheckFileNameValid(const std::string &fileName, std::string fileType) { - if (fileName.length() <= strlen(VALID_SNAPSHOT_SUFFIX)) { + std::cout << "fileType: " << fileType << std::endl; + size_t fileMinLength = (fileType == "png") ? strlen(VALID_SNAPSHOT_PNG_SUFFIX) : strlen(VALID_SNAPSHOT_SUFFIX); + if (fileName.length() <= fileMinLength) { std::cout << "error: fileName " << fileName.c_str() << " invalid, file length too short!" << std::endl; return false; } @@ -133,13 +137,12 @@ bool SnapShotUtils::CheckFileNameValid(const std::string &fileName) } // check file suffix - const char *fileNameSuffix = fileName.c_str() + (fileName.length() - strlen(VALID_SNAPSHOT_SUFFIX)); - if (strncmp(fileNameSuffix, VALID_SNAPSHOT_SUFFIX, strlen(VALID_SNAPSHOT_SUFFIX)) == 0) { + const char *fileNameSuffix = fileName.c_str() + (fileName.length() - fileMinLength); + const char *fileSuffix = (fileType == "png") ? VALID_SNAPSHOT_PNG_SUFFIX : VALID_SNAPSHOT_SUFFIX; + if (strncmp(fileNameSuffix, fileSuffix, fileMinLength) == 0) { return true; // valid suffix } - - std::cout << "error: fileName " << fileName.c_str() << - " invalid, suffix must be " << VALID_SNAPSHOT_SUFFIX << std::endl; + std::cout << "error: fileName " << fileName.c_str() << " invalid, suffix must be " << fileSuffix << std::endl; return false; } @@ -211,9 +214,9 @@ bool SnapShotUtils::RGB565ToRGB888(const uint8_t* rgb565Buf, uint8_t *rgb888Buf, rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] = (rgb565[i] & RGB565_MASK_RED); rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] = (rgb565[i] & RGB565_MASK_GREEN) >> SHIFT_5_BIT; rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] = (rgb565[i] & RGB565_MASK_BLUE) >> SHIFT_11_BIT; - rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] <<= SHITF_3_BIT; + rgb888Buf[i * RGB888_PIXEL_BYTES + R_INDEX] <<= SHIFT_3_BIT; rgb888Buf[i * RGB888_PIXEL_BYTES + G_INDEX] <<= SHIFT_2_BIT; - rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] <<= SHITF_3_BIT; + rgb888Buf[i * RGB888_PIXEL_BYTES + B_INDEX] <<= SHIFT_3_BIT; } return true; } @@ -355,12 +358,12 @@ bool SnapShotUtils::WriteToJpeg(int fd, const WriteToJpegParam ¶m) return ret; } -bool SnapShotUtils::SaveSnapShot(const std::string &fileName, Media::PixelMap &pixelMap) +bool SnapShotUtils::SaveSnapShot(const std::string &fileName, Media::PixelMap &pixelMap, std::string fileType) { OHOS::Media::ImagePacker imagePacker; OHOS::Media::PackOption option; - option.format = "image/jpeg"; - option.quality = PACKER_QUALITY; + option.format = (fileType == "png") ? "image/png" : "image/jpeg"; + option.quality = (fileType == "png") ? PNG_PACKER_QUALITY : PACKER_QUALITY; option.numberHint = 1; std::set formats; auto ret = imagePacker.GetSupportedFormats(formats); @@ -412,7 +415,7 @@ bool SnapShotUtils::ProcessDisplayId(Rosen::DisplayId &displayId, bool isDisplay } else { bool validFlag = false; auto displayIds = DisplayManager::GetInstance().GetAllDisplayIds(); - for (auto id: displayIds) { + for (auto id : displayIds) { if (displayId == id) { validFlag = true; break; @@ -421,7 +424,7 @@ bool SnapShotUtils::ProcessDisplayId(Rosen::DisplayId &displayId, bool isDisplay if (!validFlag) { std::cout << "error: displayId " << static_cast(displayId) << " invalid!" << std::endl; std::cout << "tips: supported displayIds:" << std::endl; - for (auto dispId: displayIds) { + for (auto dispId : displayIds) { std::cout << "\t" << dispId << std::endl; } return false; @@ -430,7 +433,7 @@ bool SnapShotUtils::ProcessDisplayId(Rosen::DisplayId &displayId, bool isDisplay return true; } -bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdArgments) +bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArguments &cmdArguments) { int opt = 0; const struct option longOption[] = { @@ -438,25 +441,29 @@ bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdA { "width", required_argument, nullptr, 'w' }, { "height", required_argument, nullptr, 'h' }, { "file", required_argument, nullptr, 'f' }, + { "type", required_argument, nullptr, 't' }, { "help", required_argument, nullptr, 'm' }, { nullptr, 0, nullptr, 0 } }; - while ((opt = getopt_long(argc, argv, "i:w:h:f:m", longOption, nullptr)) != -1) { + while ((opt = getopt_long(argc, argv, "i:w:h:f:t:m", longOption, nullptr)) != -1) { switch (opt) { case 'i': // display id - cmdArgments.displayId = static_cast(atoll(optarg)); - cmdArgments.isDisplayIdSet = true; + cmdArguments.displayId = static_cast(atoll(optarg)); + cmdArguments.isDisplayIdSet = true; break; case 'w': // output width - cmdArgments.width = atoi(optarg); - cmdArgments.isWidthSet = true; + cmdArguments.width = atoi(optarg); + cmdArguments.isWidthSet = true; break; case 'h': // output height - cmdArgments.height = atoi(optarg); - cmdArgments.isHeightSet = true; + cmdArguments.height = atoi(optarg); + cmdArguments.isHeightSet = true; break; case 'f': // output file name - cmdArgments.fileName = optarg; + cmdArguments.fileName = optarg; + break; + case 't': // output file type + cmdArguments.fileType = optarg; break; case 'm': // help default: @@ -465,18 +472,18 @@ bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdA } } - if (!ProcessDisplayId(cmdArgments.displayId, cmdArgments.isDisplayIdSet)) { + if (!ProcessDisplayId(cmdArguments.displayId, cmdArguments.isDisplayIdSet)) { return false; } - if (cmdArgments.fileName == "") { - cmdArgments.fileName = GenerateFileName(); - std::cout << "process: set filename to " << cmdArgments.fileName.c_str() << std::endl; + if (cmdArguments.fileName == "") { + cmdArguments.fileName = GenerateFileName(cmdArguments.fileType); + std::cout << "process: set filename to " << cmdArguments.fileName.c_str() << std::endl; } // check fileName - if (!SnapShotUtils::CheckFileNameValid(cmdArgments.fileName)) { - std::cout << "error: filename " << cmdArgments.fileName.c_str() << " invalid!" << std::endl; + if (!SnapShotUtils::CheckFileNameValid(cmdArguments.fileName, cmdArguments.fileType)) { + std::cout << "error: filename " << cmdArguments.fileName.c_str() << " invalid!" << std::endl; return false; } return true; diff --git a/snapshot/test/unittest/snapshot_display_test.cpp b/snapshot/test/unittest/snapshot_display_test.cpp index 1a27a3f5b7..cc820503d1 100644 --- a/snapshot/test/unittest/snapshot_display_test.cpp +++ b/snapshot/test/unittest/snapshot_display_test.cpp @@ -114,7 +114,7 @@ HWTEST_F(SnapshotDisplayTest, ScreenShotCmdValid01, Function | MediumTest | Leve int i; for (i = 0; i < testTimeCount_; i++) { - imgPath[i] = SnapShotUtils::GenerateFileName(i); + imgPath[i] = SnapShotUtils::GenerateFileName("jpeg", i); if (CheckFileExist(imgPath[i])) { remove(imgPath[i].c_str()); } @@ -143,7 +143,7 @@ HWTEST_F(SnapshotDisplayTest, ScreenShotCmdValid02, Function | MediumTest | Leve int i; for (i = 0; i < testTimeCount_; i++) { - imgPath[i] = SnapShotUtils::GenerateFileName(i); + imgPath[i] = SnapShotUtils::GenerateFileName("jpeg", i); if (CheckFileExist(imgPath[i])) { remove(imgPath[i].c_str()); } @@ -233,6 +233,36 @@ HWTEST_F(SnapshotDisplayTest, ScreenShotCmdValid08, Function | MediumTest | Leve std::string extraParam = "-i " + std::to_string(defaultId_) + " -m"; ASSERT_EQ(false, TakeScreenshotBySpecifiedParam(defaultCmd_, imgPath, extraParam)); } + +/** + * @tc.name: ScreenShotCmdValid + * @tc.desc: screenshot png type + * @tc.type: FUNC + */ +HWTEST_F(SnapshotDisplayTest, ScreenShotCmdValid09, Function | MediumTest | Level2) +{ + std::string imgPath[testTimeCount_]; + int i; + + for (i = 0; i < testTimeCount_; i++) { + imgPath[i] = SnapShotUtils::GenerateFileName("png", i); + if (CheckFileExist(imgPath[i])) { + remove(imgPath[i].c_str()); + } + } + + const std::string cmd = defaultCmd_ + " -t png"; + (void)system(cmd.c_str()); + + for (i = 0; i < testTimeCount_; i++) { + if (CheckFileExist(imgPath[i])) { // ok + remove(imgPath[i].c_str()); + ASSERT_TRUE(true); + return; + } + } + ADD_FAILURE(); // fail, can't find snapshot file +} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file