2012-01-22 2 views
2

Я использую Graphics32 для обработки изображений. Рассматривая его возможности, мне кажется, что я еще не видел правильной реализации обтравочной маски. Я вижу, что термин «обрезка» появляется здесь и там, но, похоже, он ссылается на что-то еще.Создание обтравочной маски с использованием Graphics32

Проще говоря, мне нужно, чтобы один слой функционировал как «подглядывающее отверстие» к другому; слой A должен проецироваться на слой B, но только там, где видны B. (Я больше не вижу необходимости переопределять, что такое обтравочная маска.)

Если бы это был только растровый рисунок этого другого слоя, который я бы хотел представить, это было бы не так сложно сделать - тогда я мог бы используйте this trick - но то, что усложняет ситуацию, заключается в том, что растровое изображение слоя не говорит о том, что будет отображаться слоем; слой может быть:

  • (частично) невидимый (когда вне поля зрения)
  • перемещено/растянутый + опционально передискретизируется
  • повернут

без каких-либо воздействий на его битовой карте.

Действительно ли это так, что для этого нет готовой реализации? Любые предложения для этого?

Прогресс

Я нашел несколько полезных элементов в источнике Graphics32. Например, с помощью этой декларации:

type 
    TLayerAccess = class(TBitmapLayer); 

, чтобы получить доступ к защищенным методам, я могу назвать TLayerAccess(ABitmapLayer).Paint(ABitmap32) иметь только этот слой окрашен в растровое изображение, точно так, как это было бы на экране.

+0

graphics32 использует только 32-битные растровые изображения, и это альфа-канал растрового изображения, который используется для смешивания. Я не знаю другого альфа-поля, которое вы можете использовать (например, область отсечения и т. Д.). У вас есть еще одна «мастер-альфа». Я бы. 1. определить альфа-растровое изображение (все белые, альфа-канал - это обтравочный путь в растровых координатах), умножить исходное растровое изображение на это, а затем отобразить растровое изображение в пункт назначения. –

+0

Как вы определяете, какие части слоя B видны? – iamjoosy

+0

@iamjoosy Я могу увидеть его, когда он нарисован на контейнере (TImage32). –

ответ

0

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

Вы хотите связать один TBitmapLayer с другим и считать его своей маской. Однако я хочу избежать этих ссылок (и его потенциальные проблемы и переработку Graphics32) и увидеть это только в крайнем случае.

Существует способ обойтись без специального TBitmapLayer, используя собственный объединитель пикселей. Но он не знает о TBitmapLayers и XY-пикселях.

Для правильной окклюзии (или выйти из) частей TBitmapLayer во время рисования на экране, вы можете использовать создать метод type TPixelCombineEvent и назначая это в качестве своего OnPixelCombine и установка TBitmapLayer.DrawMode к dmCustom.

Внутри этого метода TPixelCombineEvent вы решили, что пиксели Приводимый фон B и переднего плана F с учетом нынешнего M мастер-альфа.

procedure TMyObj.MyPixCombine(F: TColor32; var B: TColor32; M: TColor32); 
begin 
    if not PseudoThisPixelShouldBeMasked then B := F; // ugly and aliased 
end; 

Проблема здесь в том, что (код псевдо) PseudoThisPixelShouldBeMasked не знает, что такое пиксель, это касается и того, что находится внутри маски.Поэтому вам нужно извлечь это значение из компонента F, например его значения Alpha.

В то время я выбрал довольно быстро B := ColorMin(F,B);, где F - черный или белый. Этот слой всегда сверху, и в результате получается не черный, а прозрачный. Это потому, что любой рендеринг TBitmapLayer уничтожит данные маски, и мне нужно будет его повторно применить. Однако использование TByteMap, как было предложено ниже (кто проигнорировал это?) Iamjoosy, может быть интересным, возможно, что штраф за производительность оказывается незначительным.

Смежные вопросы