Модераторы: Snowy, Alexeis, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Polyline c AntiAliasing и Прозрачностью в PNGImage 
V
    Опции темы
Flashboy
Дата 10.8.2010, 03:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



Есть ли решение, нарисовать Polyline на Canvas PNGImage или TImage c AntiAliasing и прозрачностью?
В обычном случае Polyline при прорисовке под углом выводит линии с зазубринами.
Подскажите пожалуйста кто сталкивался с подобным, бьюсь над этой задачкой уже давно, все что знал перепробовал.

Это сообщение отредактировал(а) Flashboy - 10.8.2010, 03:28
PM MAIL ICQ   Вверх
Alexeis
Дата 10.8.2010, 09:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 55
Всего: 459



Flashboy, самый простой способ удвоить высоту и ширину и рисовать линии двойной толщины, после чего уменьшить картинку усредняя цвет по 4м соседним пикселам. Но эта операция произведет сглаживание всей картинки целиком. Если сглаживать нужно отдельные элементы то такой вариант не годиться. 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Flashboy
Дата 10.8.2010, 10:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



Да не годиться!
Допустим линия Pen.Width:=5, нарисовав на Canvas TBitmap(BitMap pf32bit, заготовлен с Альфаканалом) и определив TBitmap.Tranparent:=True; TBitmap.Transparent.Color:=TBitmap.Canvas.Pixels[0,0];, получим изображение  линии с прозрачностью, но контур будет не ровный там она идет под углом.
Как сделать сглаживание контура не потеряв прозрачности изображения, либо как получить прозрачность после сглаживания не потеряв при этом качество цвета вдоль контура?

Это сообщение отредактировал(а) Flashboy - 10.8.2010, 10:15
PM MAIL ICQ   Вверх
AntonN
Дата 10.8.2010, 13:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 7
Всего: 18



Alexeis
Цитата

 Но эта операция произведет сглаживание всей картинки целиком. 

нет, для исходной картины ничего не изменится, если увеличивать ее "без качества" (я до сих пор не знаю как называется этот метод, вроде "box" в ACDSee), тупо увеличивая пиксели в 2/4 раза, а потом уменьшая мы получим все тот же пиксель, т.к. среднее арифметическое для них будет ведь равно исходному.

Пример суперсемплинга могу предложить тут http://desksoft.ru/index.php?forum=13&th=46

Добавлено через 3 минуты и 1 секунду
Чтобы не потерять прозрачность придется отдельно рисовать маску-альфаканал (в grayscale) и отдельно RGB слой, т.к. GDI обнуляет альфу. Примерно так же, как я выводил шрифты и рисовал прогрессбар в сплеше http://desksoft.ru/index.php?forum=13&th=187


--------------------
user posted image
PM MAIL WWW   Вверх
RomanEEP
Дата 10.8.2010, 20:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 424
Регистрация: 18.5.2006
Где: Коломна

Репутация: 1
Всего: 8



Может это пойдет http://www.graphics32.org/wiki/
PM MAIL   Вверх
Flashboy
Дата 10.8.2010, 21:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



Цитата(RomanEEP @ 10.8.2010,  20:01)
Может это пойдет http://www.graphics32.org/wiki/

Даже не представляю как в Graphics32 реализовать Antialiasing c прозрачностью и сохранить это в PNGImage.
Слишком громоздко получиться, вязать к проекту целую библиотеку лишь для того чтобы нарисовать линию.
Я так и не нашел в GR32 Как использовать PolyLine, не нашел ни одного примера.
Может у вас есть какие либо примеры PolyLine в GR32?
Хотелось бы найти алгоритм PolyLine с Anti-Alias и Alpha как в Photoshop, чтобы уровень искажения крайних Пикселей  был не заметен глазу и независим от угла линии.
Результат что-то в этом роде сохраненный в PNGImage:
user posted image

Это сообщение отредактировал(а) Flashboy - 10.8.2010, 22:21
PM MAIL ICQ   Вверх
x128
Дата 11.8.2010, 09:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 88
Регистрация: 29.9.2009

Репутация: 5
Всего: 7



Еще можно реализлвать на GDI+ или FastDIB, GDI+ на сколько мне известно, умеет работать с PNG, а из FastDIB можно позаимствовать процедуры рисования линий.
PM MAIL WWW   Вверх
Flashboy
Дата 11.8.2010, 13:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



Цитата(x128 @ 11.8.2010,  09:57)
Еще можно реализлвать на GDI+ или FastDIB, GDI+ на сколько мне известно, умеет работать с PNG, а из FastDIB можно позаимствовать процедуры рисования линий.

FastDib, довольно таки сложен пока для моего освоения.
А в GDI+ у меня все получилось отлично , с AntiAliasing все ровно и красиво как в Photoshop, но одно но - я так и не смог получить прозрачность.(Код приведу позже)
PM MAIL ICQ   Вверх
Flashboy
Дата 11.8.2010, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



GDI+ Неплохой результат, но получить прозрачность не удается:
Код

Unit Unit2;

Interface

Uses
   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
   Dialogs, ExtCtrls, GdiPlus, PngImage;

Type
   TForm2 = Class(TForm)
      Image1: TImage;
      Image2: TImage;
      Procedure FormCreate(Sender: TObject);
   Private
      { Private declarations }
   Public
      { Public declarations }
   End;
Var
   Form2: TForm2;
Procedure AntialiasingLine;
Implementation

{$R *.dfm}

Procedure TForm2.FormCreate(Sender: TObject);
Begin
   AntialiasingLine;
End;

Procedure AntialiasingLine;
Var
   Graphics: IGPGraphics;
   PNG: TPngImage;
   Pen: IGPPen;
   Points: Array[0..9] Of TGPPoint;
Begin
   PNG := TPngImage.CreateBlank(Color_RGB, 8, 790, 383);
   Graphics := TGPGraphics.Create(PNG.Canvas.Handle);
   Graphics.Clear(TGPColor.White);
   Pen := TGPPen.Create(TGPColor.Red, 5);
   Graphics.SmoothingMode := SmoothingModeHighQuality;
   Points[0].Initialize(1, 350);
   Points[1].Initialize(170, 350);
   Points[2].Initialize(200, 80);
   Points[3].Initialize(320, 80);
   Points[4].Initialize(340, 370);
   Points[5].Initialize(460, 370);
   Points[6].Initialize(480, 80);
   Points[7].Initialize(600, 80);
   Points[8].Initialize(620, 350);
   Points[9].Initialize(789, 350);
   Graphics.DrawLines(Pen, Points);
 //PNG.TransparentColor := PNG.Canvas.Pixels[0, 0];
 //PNG.Transparent := True;
   Form2.Image1.Picture.Assign(PNG);

End;
End.


user posted image

Если же раскомментировать 2 строчки:
 
Код

 PNG.TransparentColor := PNG.Canvas.Pixels[0, 0];
 PNG.Transparent := True;

То результат:
user posted image


Это сообщение отредактировал(а) Flashboy - 11.8.2010, 15:45
PM MAIL ICQ   Вверх
AntonN
Дата 11.8.2010, 17:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 7
Всего: 18



TransparentColor и альфаканал - разные вещи, зачем ты его постоянно дергаешь?
То, что представлено на последнем скрине совершенно нормальная ситуация. Ты получаешь линию, которая была нарисована на отдельном буфере на белом фоне. Не трудно предположить, что после того как ты попробуешь нарисовать этот буфер где либо будет проглядывать фон. Вывод - рисуй красную линию на буфере закрашенном красным цветом.

Либо копируй часть своей картинки, на которой ведется рисование на буфер GDI+, рисуй линию с АА, и копируй потом буфер обратно на картинку.

Добавлено через 3 минуты и 45 секунд
Я выше тебе дал пару ссылок.
Отстань от PNG, рисуй все промежуточные шаги на Tbitmap с альфаканалом. Загоняй в них свои исходные PNG, после всех рисований в финале перегоняй Tbitmap в PNG. А так ты будешь костыль на костыле вертеть, все равно пнг преобразуется в подобие битмапа, не ведется с ним работа "напрямую".
Разберись с механизмами доступа к каналам пикселя через scanline и простыми алгоритмами блитинга, и ты сам сможешь наваять красивые вещи без костылей и ожидания на форуме.

Добавлено через 5 минут и 49 секунд
И как бы в дополнение. Если имеется что-то типа редактора или "живого" графика, то оптимальней рисовать всю мишуру на одном буфере и выводить его на форму (или в image загонять). У меня есть сомнения что ты используешь для этого несколько контролов - в совокупности с альфой это может потом вылезти боком.


--------------------
user posted image
PM MAIL WWW   Вверх
Flashboy
Дата 11.8.2010, 17:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



AntonN, вы просто знаете подход к моему мозгу, несколько ключевых фраз и 10 мин. работы и логических измышлений, и Вуаля - все как я и хотел:
user posted image

Огромное спасибо что в очередной раз подталкиваете на здравую мысль.

P.S. Если кому интересно решение исходник выложу следующим постом.

Это сообщение отредактировал(а) Flashboy - 11.8.2010, 18:28
PM MAIL ICQ   Вверх
Flashboy
Дата 11.8.2010, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



Как и обещал:
Код

Unit Unit2;

Interface

Uses
   Windows,  SysUtils, Variants,  Graphics,  Forms,
   ExtCtrls, GdiPlus, PngImage, GraphUtil, Classes, Controls;
Const
   MaxPixelCountA = MaxInt Div SizeOf(TRGBQuad);
Type
   PRGBAArray = ^TRGBAArray;
   TRGBAArray = Array[0..MaxPixelCountA - 1] Of TRGBQuad;
   TForm2 = Class(TForm)
      Image1: TImage;
      Image2: TImage;
      Procedure FormCreate(Sender: TObject);
   Private
      { Private declarations }
   Public
      { Public declarations }
   End;
Var
   Form2: TForm2;
Procedure BuildPNG2BMP(png: TPNGImage; bmp: tbitmap);
Procedure BuildBMP2PNG(bmp: Tbitmap; PNG: TPngImage);
Procedure AntialiasingLine(Image: TImage; Color: TColor);
Implementation

{$R *.dfm}

Procedure TForm2.FormCreate(Sender: TObject);
Begin
   AntialiasingLine(Image1, clRed);
End;

Procedure AntialiasingLine(Image: TImage; Color: TColor);
Var
   Graphics: IGPGraphics;
   PNG: TPngImage;
   Pen: IGPPen;
   AColor: TGPColor;
   Points: Array[0..9] Of TGPPoint;
   BTOut: Tbitmap;
Begin
   BTOut := Tbitmap.Create;
   BTOut.SetSize(790, 383);
   PNG := TPngImage.Create;
   Graphics := TGPGraphics.Create(BTOut.Canvas.Handle);
   AColor := TGPColor.CreateFromColorRef(Color);
   Graphics.Clear(AColor);
   Pen := TGPPen.Create(AColor, 5);
   Graphics.SmoothingMode := SmoothingModeHighQuality;
   Points[0].Initialize(1, 350);
   Points[1].Initialize(170, 350);
   Points[2].Initialize(200, 80);
   Points[3].Initialize(320, 80);
   Points[4].Initialize(340, 370);
   Points[5].Initialize(460, 370);
   Points[6].Initialize(480, 80);
   Points[7].Initialize(600, 80);
   Points[8].Initialize(620, 350);
   Points[9].Initialize(789, 350);
   Graphics.DrawLines(Pen, Points);
   BuildBMP2PNG(BTOut, PNG);
   Image.Picture.Assign(PNG);
   FreeANDNil(BTout);
   FreeANDNil(PNG);
End;

Procedure BuildPNG2BMP(png: TPNGImage; bmp: tbitmap);
Var
   iii, ii: integer;
   PNB: TPngImage;
   fff: PRGBAArray;
   aaa: pByteArray;
Begin
   PNB := TPngImage.Create;
   Try
      PNB.Assign(png);
      pnb.CreateAlpha;
      bmp.Assign(pnb);
      bmp.PixelFormat := pf32bit;
      For ii := 0 To bmp.Height - 1 Do
      Begin
         fff := bmp.ScanLine[ii];
         aaa := pnb.AlphaScanline[ii];
         For iii := 0 To bmp.Width - 1 Do
         Begin
            fff[iii].rgbReserved := aaa[iii];
         End;
      End;
   Finally
      PNB.free;
   End;
End;
//==========================================================

//==========================================================

Procedure BuildBMP2PNG(bmp: Tbitmap; PNG: TPngImage);
Var
   iii, ii: integer;
   PNB: TPngImage;
   fff: PRGBAArray;
   aaa: pByteArray;
Begin
   PNB := TPngImage.Create;
   Try
      PNB.Assign(bmp);
      pnb.CreateAlpha;
      For ii := 0 To bmp.Height - 1 Do
      Begin
         fff := bmp.ScanLine[ii];
         aaa := pnb.AlphaScanline[ii];
         For iii := 0 To bmp.Width - 1 Do
         Begin
            aaa[iii] := fff[iii].rgbReserved;
         End;
      End;
      PNG.Assign(PNB);
   Finally
      PNB.free;
   End;
End;
End.




И кстати никто не знает Как в GDI+ использовать в IGPGraphics.SmoothingMode равным SmoothingModeAntiAlias8x8?
 В исходнике и примерах есть, а при использовании пишет Undeclared identifier: 'SmoothingModeAntiAlias8x8

Это сообщение отредактировал(а) Flashboy - 13.8.2010, 00:33
PM MAIL ICQ   Вверх
AntonN
Дата 11.8.2010, 19:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 491
Регистрация: 8.8.2006

Репутация: 7
Всего: 18



а зачем так много? 4х вполне качественно выглядит


--------------------
user posted image
PM MAIL WWW   Вверх
Flashboy
Дата 11.8.2010, 19:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 41
Регистрация: 13.3.2010

Репутация: нет
Всего: нет



Цитата(AntonN @ 11.8.2010,  19:19)
а зачем так много? 4х вполне качественно выглядит

Мне ради принципа и ради саморазвития интересно это использовать.
В модуле GDIPlus.pas описаны режимы:
Код

//---------------------------------------------------------------------------
// Smoothing Mode
//---------------------------------------------------------------------------

type
  TGPSmoothingMode = (
    SmoothingModeInvalid     = Ord(QualityModeInvalid),
    SmoothingModeDefault     = Ord(QualityModeDefault),
    SmoothingModeHighSpeed   = Ord(QualityModeLow),
    SmoothingModeHighQuality = Ord(QualityModeHigh),
    SmoothingModeNone,
    SmoothingModeAntiAlias
    {$IF (GDIPVER >= $0110)}
    ,
    SmoothingModeAntiAlias8x4 = Ord(SmoothingModeAntiAlias),
    SmoothingModeAntiAlias8x8
    {$IFEND}
    );


Хотелось бы последний использовать:
Код

    SmoothingModeAntiAlias8x8


 А если нет, то кто знает почему поделитесь пожалуйста!?

Это сообщение отредактировал(а) Flashboy - 12.8.2010, 02:35
PM MAIL ICQ   Вверх
RomanEEP
Дата 12.8.2010, 20:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 424
Регистрация: 18.5.2006
Где: Коломна

Репутация: 1
Всего: 8



Закомментарь 2 строчки с фигурными скобками так:
Код

type
  TGPSmoothingMode = (
    SmoothingModeInvalid     = Ord(QualityModeInvalid),
    SmoothingModeDefault     = Ord(QualityModeDefault),
    SmoothingModeHighSpeed   = Ord(QualityModeLow),
    SmoothingModeHighQuality = Ord(QualityModeHigh),
    SmoothingModeNone,
    SmoothingModeAntiAlias
    //{$IF (GDIPVER >= $0110)}
    ,
    SmoothingModeAntiAlias8x4 = Ord(SmoothingModeAntiAlias),
    SmoothingModeAntiAlias8x8
    //{$IFEND}
    );

но чтобы быьб уверенным в работоспособности своего кода на других компах надо видимо в коде делать проверки на версию библиотеки.
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Звук, графика и видео"
Girder
Snowy
Alexeis

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делится вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • По вопросам разработки игр стоит заглянуть сюда

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Girder, Snowy.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Звук, графика и видео | Следующая тема »


 




[ Время генерации скрипта: 0.0877 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.