因此,对于我们正在尝试创建的应用程序,我们希望将一个独立应用程序的Unity窗口透明化(除几个按钮之外的所有按钮),并让用户一起拍摄其View / OS + unity层的屏幕快照。
这样的例子:用户打开我们的应用程序,单击一个按钮,整个统一窗口(除了几个按钮之外都是透明的)。然后,用户可以像平常一样使用它的操作系统,而前面提到的按钮仍位于顶部。然后,用户可以单击按钮来创建其操作系统的屏幕截图,然后将其保存到他们的系统中。例如,通过这种方式,我们可以通过屏幕快照在用户OS顶部的Unity(3D模型,图像)中显示任何内容。
目前,我们可以使用类似以下的模拟设置来使窗口透明:https : //alastaira.wordpress.com/2015/06/15/creating-windowless-unity-applications/
效果很好,在Windows等中单击也可以。但是,我们现在想创建一个屏幕截图并将其保存在某处。为此,我们尝试了多种方法,几年前,我们将该项目搁置一旁,通过一个自定义的dll对其进行了工作,该dll使用了我们内部统一调用的“ using System.Drawing”代码。请在下面查看此dll和代码的示例。
using System.Drawing;
namespace ScreenShotDll
{
public class ScreenShotClass
{
public static void TakeScreenShotRect(int srcX, int srcY, int dstX, int dstY) //both fullscreen screenshot and cropped rectangle screenshot
{
int width = Math.Abs(srcX - dstX);
int height = Math.Abs(srcY - dstY);
Bitmap memoryImage;
memoryImage = new Bitmap(width, height);
Size s = new Size(memoryImage.Width, memoryImage.Height);
Graphics memoryGraphics = Graphics.FromImage(memoryImage);
memoryGraphics.CopyFromScreen(srcX, srcY, 0, 0, s);
string str = "";
try
{
str = string.Format(AppDomain.CurrentDomain.BaseDirectory + @"Screenshot.png");
}
catch (Exception er)
{
Console.WriteLine("Sorry, there was an error: " + er.Message);
Console.WriteLine();
}
memoryImage.Save(str);
}
但是,这似乎不再起作用。我们在Unity的IL2CPP后端上,看到错误:NotSupportedException: System.Drawing.Bitmap
我们还尝试在Unity中使用user32.dll,并使用GetPixel,ReleaseDC和GetActiveWindow函数(在几个论坛上发布),但是我们所得到的只是一张白色图片。
调整我们的自定义dll的任何方法或执行此操作的任何其他方法将不胜感激。如果您需要更多信息,请告诉我。
几天后,我设法在Unity内部解决了这个问题。
我使用以下代码制作了窗口的屏幕截图,并将其保存到位图。然后将其保存到我的磁盘上。
[DllImport("user32.dll", SetLastError = true)] static extern int GetSystemMetrics(int smIndex);
[DllImport("user32.dll", SetLastError = false)] static extern IntPtr GetDesktopWindow();
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC", SetLastError=true)] static extern IntPtr CreateCompatibleDC([In] IntPtr hdc);
[DllImport("gdi32.dll", EntryPoint = "DeleteDC")] public static extern bool DeleteDC([In] IntPtr hdc);
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")] public static extern bool DeleteObject([In] IntPtr hObject);
[DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")] static extern IntPtr CreateCompatibleBitmap([In] IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll", EntryPoint = "SelectObject")] public static extern IntPtr SelectObject([In] IntPtr hdc, [In] IntPtr hgdiobj);
[DllImport("gdi32.dll", EntryPoint = "BitBlt", SetLastError = true)] static extern bool BitBlt([In] IntPtr hdc, int nXDest, int nYDest, int nWidth, int nHeight, [In] IntPtr hdcSrc, int nXSrc, int nYSrc, uint dwRop);
private void screenShot()
{
Debug.Log("In screenShot!");
int nScreenWidth = GetSystemMetrics(0);
int nScreenHeight = GetSystemMetrics(1);
IntPtr hDesktopWnd = GetDesktopWindow();
IntPtr hDesktopDC = GetDC(hDesktopWnd);
IntPtr hCaptureDC = CreateCompatibleDC(hDesktopDC);
IntPtr hCaptureBitmap = CreateCompatibleBitmap(hDesktopDC, nScreenWidth, nScreenHeight);
SelectObject(hCaptureDC, hCaptureBitmap);
BitBlt(hCaptureDC, 0, 0, nScreenWidth, nScreenHeight, hDesktopDC, 0, 0, 0x00CC0020 | 0x40000000);
Bitmap bmp = Image.FromHbitmap(hCaptureBitmap);
ImageConverter converter = new ImageConverter();
byte[] bytes = (byte[])converter.ConvertTo(bmp, typeof(byte[]));
string path = Application.dataPath;
if (Application.platform == RuntimePlatform.OSXPlayer) {
path += "/../../";
}
else if (Application.platform == RuntimePlatform.WindowsPlayer) {
path += "/../";
}
File.WriteAllBytes(path + "Screenshot" + ".png", bytes);
ReleaseDC(hDesktopWnd, hDesktopDC);
DeleteDC(hCaptureDC);
DeleteObject(hCaptureBitmap);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句