2015-02-15 2 views
1

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

private void Form1_Paint(object sender, PaintEventArgs e) 
{ 
    var srcPoint = new Point(0,0); 
    var dstPoint = new Point(Screen.PrimaryScreen.Bounds.Width/2, Screen.PrimaryScreen.Bounds.Height/2); 
    var copySize = new Size(100, 100); 

    e.Graphics.CopyFromScreen(srcPoint, dstPoint, copySize, CopyPixelOperation.SourceCopy); 
} 

Функция CopyFromScreen игнорирует любые клипы, установленные перед ним.

e.SetClip(new Rectangle(srcPoint.X, srcPoint.Y, 20, 20)); 

Я делаю что-то неправильно или это неправильный подход.

Для контекста: Я пытаюсь смягчить проблему широкоэкранного интерфейса UI, копируя HUD по краям и располагаясь ближе к центру.

Я знаю, что FlawlessWidescreen, но он не поддерживает многие менее популярные игры. Я предполагаю, что тыкать в памяти (что безупречно) может также работать, но почти всегда против TOS.

Редактировать: Конечная цель - скопировать произвольный путь как форму, а не простой прямоугольник (я надеялся на маску изображения).

Редактировать # 2: Таким образом, у меня есть нерегулярная форма, нарисованная каждые 100 мс. Оказывается, это просто болотит игру до тех пор, пока я не замедлю ее до каждых 500 мс. Но все же игра негладкая. Эта операция копирования и рисования изображения будет слишком тяжелой для операции в GDI +? Я думал, что это достаточно просто, чтобы ничего не заглушить.

Мысли перед тем, как пометить ответ как принятый?

ответ

2

Я предполагаю, что это действительно неправильный подход.

ClippingRegion The используется только для отсечения DrawXXX и FillXXX команды, в том числе DrawImage (!).

CopyFromScreen однако будет использовать данный Points и Size и не клип источника.

Для региона Rectangle это не проблема, так как вы можете достичь того же результата, выбрав подходящие значения Point и Size.

Но как только вы нацелитесь на использование более интересных областей отсечения, вам придется использовать промежуточный Bitmap, на который вы скопируете с экрана и с которого вы можете использовать DrawImage в обрезанный регион.

Для этого вы можете создать более или менее сложные GraphicsPaths.

Вот пример кода:

После ввода cliping координаты в Rectangle или GraphicsPath clip вы можете написать что-то вроде этого:

e.Graphics.SetClip(clip); 

using (Bitmap bitmap = new Bitmap(ClientSize.Width, ClientSize.Height)) 
{ 
    using (Graphics G = Graphics.FromImage(bitmap)) 
      G.CopyFromScreen(dstPoint, srcPoint, 
          copySize, CopyPixelOperation.SourceCopy); 
    e.Graphics.DrawImage(bitmap, 0, 0); 
} 
+0

Спасибо. Я действительно начал спускаться по этой дороге. Я не совсем обнял графику и битмапы. и теперь я думаю, что понял. Графика - это всего лишь оболочка вокруг другого источника. Так что, будь то HDC или изображение, это не имеет значения. Но вы никогда не копируете графику, вы должны смотреть на источник того, на что указывает графический объект. – aitee

+0

Да: Класс Graphics - это инструмент, который вы используете для работы с растровым изображением некоторого источника, будь то файл или поверхность управления или битмап чистой памяти; он имеет множество методов и некоторых свойств для управления тем, как он работает, но в нем нет графических данных, то есть нет пикселей. – TaW

+0

У вас есть какие-либо комментарии к Edit # 2? Является ли простая копия изображения вне диапазона для производительности для GDI +? – aitee

0

Если не было бы

e.Graphics.Clip = myRegion; 
+0

вероятно опечатка в коде ОПС не компилируется. – TaW

+0

Да, извините.Я не просто копировал свой код, чтобы он был кратким (набран в соответствующих частях). То, что у меня на самом деле было в моем коде, было «e.Graphics.SetClip (...);». Я предполагаю/верю, что нет никакой разницы в этом и том, что вы опубликовали. – aitee