我正在制作一个程序,以便在我流式传输时拍摄游戏的屏幕截图,因此需要截屏并自动保存,但是当我将游戏设置为使用OpenGL时,我的功能会失败,它会一直保存图像一遍又一遍,它只是在我重新开始游戏后改变图像。
它似乎在第一次运行时有效,但在下一次运行时它会保存第一张图像。
以下是我正在使用的内容:
public static Bitmap PrintWindow(IntPtr hwnd) {
try {
RECT rc;
GetClientRect(hwnd, out rc);
IntPtr hdcFrom = GetDC(hwnd);
IntPtr hdcTo = CreateCompatibleDC(hdcFrom);
//X and Y coordinates of window
int Width = rc.right;
int Height = rc.bottom;
Bitmap bmp = null;
IntPtr hBitmap = CreateCompatibleBitmap(hdcFrom, Width, Height);
if (hBitmap != IntPtr.Zero) {
// adjust and copy
IntPtr hLocalBitmap = SelectObject(hdcTo, hBitmap);
BitBlt(hdcTo, 0, 0, Width, Height, hdcFrom, 0, 0, CopyPixelOperation.SourceCopy);
SelectObject(hdcTo, hLocalBitmap);
//We delete the memory device context.
DeleteDC(hdcTo);
//We release the screen device context.
ReleaseDC(hwnd, hdcFrom);
//Image is created by Image bitmap handle and assigned to Bitmap variable.
bmp = System.Drawing.Image.FromHbitmap(hBitmap);
//Delete the compatible bitmap object.
DeleteObject(hBitmap);
bmp.Save("saving.png", System.Drawing.Imaging.ImageFormat.Png);
}
return bmp;
}
catch {
}
return new Bitmap(0, 0);
}
如果我改变游戏图形以使用DirectX它运行良好,它只是在使用OpenGL时发生,所以如果它对于openGL窗口必须是不同的,或者如果它不可能捕获那种窗口,那就不要了。
答案 0 :(得分:4)
使用双缓冲OpenGL与使用GDI操作¹是互斥的。使用namespace Drupal\api_articles\Plugin\rest\resource;
use Drupal\Core\Session\AccountProxyInterface;
use Drupal\rest\Plugin\ResourceBase;
use Drupal\rest\ResourceResponse;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Psr\Log\LoggerInterface;
/**
* Provides a resource to get view modes by entity and bundle.
*
* @RestResource(
* id = "article_rest_resource",
* label = @Translation("Article rest resource"),
* uri_paths = {
* "canonical" = "/api/v1/articles",
* "https://www.drupal.org/link-relations/create" = "/api/v1/articles"
* }
* )
*/
class ArticleRestResource extends ResourceBase {
/**
* A current user instance.
*
* @var \Drupal\Core\Session\AccountProxyInterface
*/
protected $currentUser;
/**
* Constructs a Drupal\rest\Plugin\ResourceBase object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param array $serializer_formats
* The available serialization formats.
* @param \Psr\Log\LoggerInterface $logger
* A logger instance.
* @param \Drupal\Core\Session\AccountProxyInterface $current_user
* A current user instance.
*/
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
array $serializer_formats,
LoggerInterface $logger,
AccountProxyInterface $current_user) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger);
$this->currentUser = $current_user;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->getParameter('serializer.formats'),
$container->get('logger.factory')->get('api_articles'),
$container->get('current_user')
);
}
/**
* Responds to GET requests.
*
* Returns a list of bundles for specified entity.
*
* @throws \Symfony\Component\HttpKernel\Exception\HttpException
* Throws exception expected.
*/
public function get() {
// You must to implement the logic of your REST Resource here.
// Use current user after pass authentication to validate access.
if (!$this->currentUser->hasPermission('access content')) {
throw new AccessDeniedHttpException();
}
return new ResourceResponse("Implement REST State GET!");
}
}
截取屏幕截图。
¹:嗯,从技术上讲,如果你知道自己在做什么,并采取正确的预防措施,你可以将它们混合在一起。但它比值得做的更麻烦。
答案 1 :(得分:0)
在最近的Windows 10更新后,DirectX渲染窗口现在遇到了同样的问题。我发现了一种解决方法,但你不会喜欢它...... 如果你设置hwnd = 0,BitBlt现在指的是整个屏幕,而不只是一个窗口。然后,您可以更改BitBlt的源偏移值以仅捕获目标窗口 虽然这有效,但它比原来的方式要慢得多。 :( 在我的笔记本电脑上,抓住一个1080p的窗口过去需要3ms,但现在,使用这种解决方法,它需要27ms,这真的破坏了流媒体性能。 :( 不过,它总比没有好。