Clipboard
クリップボード
Win32APIを利用してTexture2Dをクリップボードに読み書きする
c++
#include "pch.h"
#include <Windows.h>
# define DLL_API extern "C" __declspec(dllexport)
// Read Clipboard
DLL_API bool hasClipboardImage() {
bool isOpened = OpenClipboard(NULL);
bool result = false;
if (isOpened) {
result = IsClipboardFormatAvailable(CF_DIB);
}
CloseClipboard();
return result;
}
static BITMAPINFO* getLockedBitmapInfoPtr() {
HANDLE hClipboardData = GetClipboardData(CF_DIB);
LPVOID clipboardDataPtr = GlobalLock(hClipboardData);
return static_cast<BITMAPINFO*>(clipboardDataPtr);
}
DLL_API void getClipboardImageSize(int* width, int* height, int* bitsPerPixel) {
bool IsOpened = OpenClipboard(NULL);
if (IsOpened && IsClipboardFormatAvailable(CF_DIB)) {
BITMAPINFO* bmpInfoPtr = getLockedBitmapInfoPtr();
if (bmpInfoPtr != nullptr) {
*width = bmpInfoPtr->bmiHeader.biWidth;
*height = bmpInfoPtr->bmiHeader.biHeight;
*bitsPerPixel = bmpInfoPtr->bmiHeader.biBitCount;
}
GlobalUnlock(bmpInfoPtr);
}
CloseClipboard();
}
DLL_API bool getClipboardImage(unsigned char* buffer) {
bool isOpened = OpenClipboard(NULL);
bool result = false;
if (!isOpened) {
CloseClipboard();
return false;
}
if (IsClipboardFormatAvailable(CF_DIB)) {
BITMAPINFO* bmpInfoPtr = getLockedBitmapInfoPtr();
if (bmpInfoPtr != nullptr) {
int width, height, bitsPerPixel;
getClipboardImageSize(&width, &height, &bitsPerPixel);
// Only24bit(JPEG), 32bit(PNG-32)
if (bitsPerPixel == 24 || bitsPerPixel == 32) {
unsigned char* pixelData = (unsigned char*)bmpInfoPtr + bmpInfoPtr->bmiHeader.biSize;
int bytesPerPixel = bitsPerPixel / 8;
if (bmpInfoPtr->bmiHeader.biCompression == BI_BITFIELDS) {
pixelData += 4 * 3;
}
int bytesPerLine = width * bytesPerPixel;
if (bytesPerLine % 4 != 0) {
bytesPerLine += 4 - (bytesPerLine % 4);
}
unsigned char* dst = buffer;
unsigned char* src = pixelData;
for (int h = 0; h < height; h++) {
memcpy(
dst + (width * h * bytesPerPixel),
src + (h * bytesPerLine),
width * bytesPerPixel
);
}
result = true;
}
}
GlobalUnlock(bmpInfoPtr);
}
CloseClipboard();
return result;
}
// Write Clipboard
DLL_API bool setClipboardImage(unsigned char* data, int width, int height) {
HANDLE hMem;
int size = width * height * 4;
if (!OpenClipboard(NULL)) {
CloseClipboard();
return false;
}
HGLOBAL hg = GlobalAlloc(GMEM_MOVEABLE, sizeof(BITMAPINFOHEADER) + size);
BITMAPINFO* pInfo = (BITMAPINFO*)GlobalLock(hg);
pInfo->bmiHeader.biSize = sizeof(BITMAPINFO);
pInfo->bmiHeader.biWidth = width;
pInfo->bmiHeader.biHeight = height;
pInfo->bmiHeader.biPlanes = 1;
pInfo->bmiHeader.biBitCount = 32;
pInfo->bmiHeader.biCompression = BI_RGB;
pInfo->bmiHeader.biSizeImage = width * height * 4;
pInfo->bmiHeader.biXPelsPerMeter = 0;
pInfo->bmiHeader.biYPelsPerMeter = 0;
pInfo->bmiHeader.biClrUsed = 0;
pInfo->bmiHeader.biClrImportant = 0;
memcpy(pInfo->bmiColors, data, size);
GlobalUnlock(hg);
EmptyClipboard();
SetClipboardData(CF_DIB, hg);
//SetClipboardData(CF_BITMAP, hg);
CloseClipboard();
return true;
}
C# DLLImport
[DllImport("libycpp")] private static extern bool hasClipboardImage();
[DllImport("libycpp")] private static extern void getClipboardImageSize(ref int width, ref int height, ref int bitsPerPixel);
[DllImport("libycpp")] private static extern bool getClipboardImage(IntPtr buffer);
[DllImport("libycpp")] private static extern bool setClipboardImage(IntPtr data, int width, int height);
C# Read
Material mat;
if (GetClipboardImage(out Texture2D tex)){
mat.mainTexture = tex;
}
C# Write
Texture2D tex;
// Prepare Data
byte[] btex = tex.GetRawTextureData();
for (int i = 0; i < btex.Length; i += 4) {
// RGBA -> BGRA
byte colR = btex[i + 0];
btex[i + 0] = btex[i + 2];
btex[i + 2] = colR;
}
// Set Data
IntPtr dataPtr = Marshal.AllocHGlobal(btex.Length);
Marshal.Copy(btex, 0, dataPtr, btex.Length);
setClipboardImage(dataPtr, tex.width, tex.height);
最終更新日:
August 14, 2023
作成日: August 14, 2023
作成日: August 14, 2023