A way is with GetCursorInfo-DrawIcon(Ex)
How to draw mouse cursor on the given image
I used winrt to capture desktop, and I need to process the captured image, then draw the mouse curson on the processed image(rgb32),
I used to opencv to draw it , but it would cause the result image lose black pixel when the cursor only has mask image.
HICON icon = nullptr;
ICONINFO ii;
icon = CopyIcon(cursorInfo.hCursor);
if (!icon) {
LOG(ERROR) << "COPY ICON FAILED";
return;
}
HBITMAP cursorBitmap = IconToBitmap(icon);
if (cursorBitmap == nullptr)
{
LOG(ERROR) << "convert icon to bitmap failed";
return;
}
cv::Mat cursorMat;
if (!HBitmap2Mat(cursorBitmap, cursorMat))
{
LOG(ERROR) << "bitmap 2 mat failed";
return;
}
cv::Point pt(std::abs(cursorInfo.ptScreenPos.x), std::abs(cursorInfo.ptScreenPos.y));
int cursorWidth = (pt.x + cursorMat.cols) > source.cols ? (source.cols - pt.x) : cursorMat.cols;
int cursorHeight = (pt.y + cursorMat.rows) > source.rows ? (source.rows - pt.y) : cursorMat.rows;
cv::Mat roi = source(cv::Rect(pt.x,pt.y, cursorWidth, cursorHeight));
cv::Mat cursorRoi = cursorMat(cv::Rect(0, 0, cursorWidth, cursorHeight));
for (int i = 0; i < cursorRoi.rows; ++i)
{
for (int j = 0; j < cursorRoi.cols; ++j)
{
cv::Vec4b& rgba = cursorRoi.at<cv::Vec4b>(i, j);
if (rgba[0]!=0x00 ) {
roi.at<cv::Vec4b>(i, j) = cursorRoi.at<cv::Vec4b>(i, j);
}
else {
}
}
}
Windows development Windows API - Win32
3 answers
Sort by: Most helpful
-
-
ADITI 1 Reputation point
2022-11-19T15:34:14.663+00:00 We can draw a mouse cursor in a image by just taking pencil and drawing sheet and eraser and start making the mouse cursor in paper firstly we should do by light hand the if it is perfect the we should dark it with pencil otherwise we should eraser it and make it again perfect after that we should shade it to give a look for more better image
-
tonyye 21 Reputation points
2022-11-24T08:29:29.77+00:00 I use the following code to draw it , and get the result image is
As you see , the edge of cursor should be black, but it lost.
I use the Winrt::Capture to capture the desktop, and I found no way to get HDC.
So I build Gdiplus::Graphics with Bitmap, not HDC.void Draw(unsigned char* buf, int width, int height)
{
Gdiplus::Bitmap bitmap(width, height, width * 4, PixelFormat32bppARGB, buf);Bitmap dstImg(width,height); Gdiplus::Graphics gps(&dstImg); gps.DrawImage(&bitmap, 0, 0); CURSORINFO cursor_info = {}; cursor_info.cbSize = sizeof(CURSORINFO); auto ret = ::GetCursorInfo(&cursor_info); if (!ret) return; if (!(cursor_info.flags & CURSOR_SHOWING)) return; ICONINFO icon_info; ret = ::GetIconInfo(cursor_info.hCursor, &icon_info); if (!ret) return; auto cursor_x = cursor_info.ptScreenPos.x; auto cursor_y = cursor_info.ptScreenPos.y; Gdiplus::SolidBrush brush(Gdiplus::Color(255, 0, 0));; gps.FillEllipse(&brush, cursor_x, cursor_y, 32, 32); HICON icon = CopyIcon(cursor_info.hCursor); HDC hmDC = gps.GetHDC(); ::DrawIconEx(hmDC, cursor_x, cursor_y, icon, 0,0, 0, NULL, DI_NORMAL); gps.ReleaseHDC(hmDC); BITMAPINFOHEADER bi; bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = width; bi.biHeight = height * (-1); bi.biPlanes = 1; bi.biBitCount = 32;//should get from system color bits bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; CLSID pngClsid; GetEncoderClsid(L"image/png", &pngClsid); dstImg.Save(L"D:\\XXXXXEEEffff.png", &pngClsid, NULL);
}