huangji731
2024-06-11 10:29:50 +08:00
parent 7b6d775879
commit 19d0f90042
4 changed files with 119 additions and 74 deletions
+9 -8
View File
@@ -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 &param);
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 &param);
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);
};
+36 -29
View File
@@ -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> display,
static bool GetScreenshotByCmdArguments(CmdArguments& cmdArguments, sptr<Display> display,
std::shared_ptr<OHOS::Media::PixelMap>& 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<OHOS::Media::PixelMap> 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> display,
static bool GetScreenshotByCmdArguments(CmdArguments& cmdArguments, sptr<Display> display,
std::shared_ptr<OHOS::Media::PixelMap>& 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;
}
+42 -35
View File
@@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "snapshot_utils.h"
#include <cerrno>
#include <climits>
@@ -29,7 +30,6 @@
#include <string>
#include <sys/time.h>
#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<MissionErrorMgr*>(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 &param)
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<std::string> 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<int64_t>(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<DisplayId>(atoll(optarg));
cmdArgments.isDisplayIdSet = true;
cmdArguments.displayId = static_cast<DisplayId>(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;
@@ -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