Делая снимки экрана в Windows Vista, Windows 7, с прозрачными областями вне региона приложения

Я пытаюсь сделать снимок экрана приложения, и я хотел бы сделать части прямоугольника, которые не являются частью региона приложений быть прозрачными. Так, например, на стандартном приложении Windows я хотел бы сделать скругленные углы прозрачными.

Я записал быстрое тестовое приложение, которое продолжает работать на XP (или перспектива/окна 7 с выключенным аэро):

    protected override void OnPaint(PaintEventArgs e)
    {
        base.OnPaint(e);

        Graphics g = e.Graphics;           

        // Just find a window to test with
        IntPtr hwnd = FindWindowByCaption(IntPtr.Zero, "Calculator");

        WINDOWINFO info = new WINDOWINFO();
        info.cbSize = (uint)Marshal.SizeOf(info);
        GetWindowInfo(hwnd, ref info);


        Rectangle r = Rectangle.FromLTRB(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
        IntPtr hrgn = CreateRectRgn(info.rcWindow.Left, info.rcWindow.Top, info.rcWindow.Right, info.rcWindow.Bottom);
        GetWindowRgn(hwnd, hrgn);

        // fill a rectangle which would be where I would probably 
        // write some mask color
        g.FillRectangle(Brushes.Red, r);

        // fill the region over the top, all I am trying to do here 
        // is show the contrast between the applications region and 
        // the rectangle that the region would be placed in
        Region region = Region.FromHrgn(hrgn);
        region.Translate(info.rcWindow.Left, info.rcWindow.Top);
        g.FillRegion(Brushes.Blue, region);
    }

Когда я запускаю это тестовое приложение на XP (или Vista/Windows 7 с Аэро прочь), я получаю что-то вроде этого, которое является большим, потому что я могу eek xor маска из этого, которое может использоваться позже с BitBlt.

удаленная мертвая ссылка Imageshack - Снимок экрана

Вот проблема на Vista, или Windows 7 с Аэро включил, существует не обязательно регион на окне, на самом деле в большинстве случаев нет. Кто-либо может помочь мне выяснить некоторый способ создать маску как это на этих платформах?

Вот некоторые подходы, которые я уже попробовал...

1. Используя функцию PrintWindow: Это не работает, потому что это отдает снимок экрана, сделанный окна с Аэро прочь, и это окно является другой формой из окна, возвращенного с Аэро на

2 Используя Настольный Менеджер окон API для получения миниатюры в натуральную величину: Это не работало, потому что это тянет непосредственно на экран и от того, что я могу сказать, что Вы не можете получить снимок экрана непосредственно из этого API. Да, я мог открыть окно с розовым фоном, показать, что миниатюра, сделать снимок экрана затем скрывают это временное окно, но это - ужасный пользовательский опыт и полный взлом, на котором у меня не было бы своего имени.

3. Использование Графики. CopyFromScreen или некоторый другой pinvoke вариант этого: Это не работает, потому что я не могу предположить, что окно, от которого я нуждаюсь в информации, во главе z-порядка на экран.

Прямо сейчас лучшее решение, о котором я могу думать, к особому случаю, Аэро в Windows 7 и Vista для ручного стирания углов трудным кодированием некоторых графических контуров, которые я закрашиваю, но это решение высосало бы, так как любое приложение, которое выполняет пользовательское очищение, повредит это.

Можно ли думать о другом или лучшем решении?

Если Вы здесь, благодарит занять время, чтобы прочитать это сообщение, я ценю любую справку или направление, которое можно предложить!

14
задан SuperBiasedMan 25 August 2015 в 10:27
поделиться

3 ответа

Если вы ищете законченное приложение, есть 7capture , который также фиксирует прозрачность, поэтому изображения можно сохранять в формате PNG для последующего компоновки.

РЕДАКТИРОВАТЬ:

Исходный вопрос и комментарии указывают на то, что вы хотите создать область в Windows Vista / 7, которую затем можно использовать для маскировки частей захваченного изображения, как это делается в Windows XP и пользовательских интерфейсах, отличных от Aero. . Использование области не даст вам желаемого результата, поскольку контур окна вычисляется не как область, а как изображение с переменной прозрачностью - RGBA. Альфа-канал в этом изображении - это ваша маска, но это не маска включения-выключения, такая как область, а постепенная маска с диапазоном значений от полностью включенных пикселей до полностью замаскированных.

Хотя он использует недокументированные API, код на http://spazzarama.wordpress.com/2009/02/12/screen-capture-with-vista-dwm/ будет записывать в буфер RGBA который затем можно использовать для рендеринга или сохранения изображения с неповрежденными тенями и другими эффектами полупрозрачности.

В DwmCapture.cs Измените

BackBufferFormat = Format.X8R8G8B8

на

BackBufferFormat = Format.A8R8G8B8

(X8-> A8)

И тогда вы сможете получить доступ как к обычным данным RGB, так и к прозрачности из захваченного буфера. Затем его можно сохранить как PNG или другой формат с альфа-каналом для создания композиции.

8
ответ дан 1 December 2019 в 15:20
поделиться

Убрана идея, которая ужасна, но была бы потрясающей в 90-х

Вы говорите, что использование DWM API позволяет делать снимки только непосредственно на экран... можно ли создать окно вне экрана (скажем, X = -100000px, Y = -100000px), но видимое (может быть, даже скрытое?) и рисовать скриншот на него? Поскольку при использовании DWM каждое окно имеет подложку, я думаю, что оно все равно будет отрисовываться нормально, даже если цель не находится непосредственно на экране.

Также, если вы хотите пойти по пути DirectX и получить доступ к фактической DX текстуре, поддерживающей окно, я нашел несколько ссылок, которые могут помочь (особенно первая ссылка):

1
ответ дан 1 December 2019 в 15:20
поделиться
  1. Использование Graphics.CopyFromScreen или другого варианта pinvoke: Это не работает, потому что я не могу Предположим, что окно мне нужно информация от находится в верхней части z-порядок на экране.

Если вы знаете, из какого окна вам нужна информация, можете ли вы вывести его на передний план, вызвать Graphics.CopyFromScreen и затем сбросить его z-index? По опыту я знаю, что Aero делает странные вещи, когда элементы находятся в фоновом режиме, чтобы их стеклянный интерфейс работал правильно (частичный рендеринг и т. Д.). Возможно, это не лучший UX; однако это будет особый случай, и он будет использоваться только при включенном Aero.

0
ответ дан 1 December 2019 в 15:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: