imdecode 可以用于剪贴板图像吗?

Can imdecode be used to clipboard image?

我想在 OpenCV 中使用 Windows 剪贴板图像数据而不使用临时文件。

我可以为此使用 imdecode 吗?

我试过了,但是 Mat 是空的:

if(!IsClipboardFormatAvailable(CF_DIB)) return;

OpenClipboard(NULL);
HGLOBAL clipboard = GetClipboardData(CF_DIB);

if(clipboard){
    char* data = (char*)GlobalLock(clipboard);
    Mat buf = Mat(1, GlobalSize(clipboard), CV_8UC1, data, Mat::AUTO_STEP);
    Mat mat = imdecode(buf, IMREAD_UNCHANGED);
    GlobalUnlock(clipboard);
}

CloseClipboard();

您似乎缺少相应的 SetClipboardData

我不知道 opencv 但通常当我使用剪贴板时我会写这样的东西

  const auto opened = OpenClipboard(GetConsoleWindow());
  if (opened)
  {
    EmptyClipboard();

    const std::string command{"hello clipboard"};

    auto* const hMem = GlobalAlloc(GMEM_MOVEABLE, (command.size() + 1));
    if (hMem == nullptr)
    {
      CloseClipboard();
      return;
    }

    auto* const p = static_cast<LPSTR>(GlobalLock(hMem));
    if (p)
    {
      memcpy_s(p, command.size(), command.data(), command.size());
      p[command.size()] = 0;
      GlobalUnlock(hMem);
      SetClipboardData(CF_TEXT, p);  <<<<<
    }
    CloseClipboard();
  }

免责声明:删除了错误处理和打印输出

您应该能够使用 CF_BITMAP 获取 HBITMAP 的句柄。然后用GetDIBits复制HBITMAPcv::Mat内存

如果由于某种原因 CF_BITMAP 不可用,请参阅此示例以获取 CF_DIB 备份,或查看可用的格式。

void copy()
{
    cv::Mat mat;

    HBITMAP hbitmap = nullptr;
    if (!::OpenClipboard(nullptr))
        return;
    if (IsClipboardFormatAvailable(CF_BITMAP))
        hbitmap = (HBITMAP)GetClipboardData(CF_BITMAP);
    if(!hbitmap && IsClipboardFormatAvailable(CF_DIB))
    {
        HANDLE handle = GetClipboardData(CF_DIB);
        LPVOID hmem = GlobalLock(handle);
        if (hmem)
        {
            BITMAPINFO* bmpinfo = (BITMAPINFO*)hmem;
            int offset = (bmpinfo->bmiHeader.biBitCount > 8) ?
                0 : sizeof(RGBQUAD) * (1 << bmpinfo->bmiHeader.biBitCount);
            BYTE* bits = (BYTE*)(bmpinfo)+bmpinfo->bmiHeader.biSize + offset;
            HDC hdc = ::GetDC(0);
            hbitmap = CreateDIBitmap(hdc, 
                &bmpinfo->bmiHeader, CBM_INIT, bits, bmpinfo, DIB_RGB_COLORS);
            ::ReleaseDC(0, hdc);
            GlobalUnlock(hmem);
        }
    }

    if (hbitmap)
    {
        BITMAP bm;
        ::GetObject(hbitmap, sizeof(bm), &bm);
        int cx = bm.bmWidth;
        int cy = bm.bmHeight;
        if (bm.bmBitsPixel == 32)
        {
        mat.create(cy, cx, CV_8UC4);
        BITMAPINFOHEADER bi = { sizeof(bi), cx, -cy, 1, 32, BI_RGB };
        GetDIBits(hdc, hbitmap, 0, cy, mat.data, (BITMAPINFO*)&bi, DIB_RGB_COLORS);
        }
    }
    CloseClipboard();
}