Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.01;
Скачать: CL | DM;

Вниз

И снова antialiasing   Найти похожие ветки 

 
Ал   (2006-03-04 15:49) [0]

Знатоки!

Пересмотрел все, что мог в Инете!
Нужен алгоритм рисования 2D полигона с антиалиасингом.
На http://www.codenet.ru/progr/video/antialiasing.php подробно описано словами. Но как запрограммировать - так и не понял!

Нужен работающий код. Если кому не жалко, помогите.

С уважением.


 
antonn ©   (2006-03-04 16:22) [1]

на лежит кнопка и TImage с картинкой bmp(!), по нажатию кнопки вызывается Button1Click. само рисование тоже в Button1Click. думаю, разберешься.

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, ExtCtrls, StdCtrls;

type
 TForm1 = class(TForm)
   Image1: TImage;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure Alias(var SourceBitmap:TBitmap; CanvasOut:TCanvas; _R:TRect);
const
 MaxPixelCount = MaxInt div SizeOf(TRGBTriple);
type
 PRGBArray = ^TRGBArray;
 TRGBArray = array[0..MaxPixelCount-1] of TRGBTriple;
var
 x,y,cx,cy,cxi,totr,totg,totb,i: Integer;
 Row1,Row2,Row3,DestRow: PRGBArray;
begin
 for Y:=0 to (SourceBitmap.Height div 3)-1 do begin
   cy := y*3;
   DestRow := SourceBitmap.ScanLine[y];
   Row1:=SourceBitmap.ScanLine[cy];
   Row2:=SourceBitmap.ScanLine[cy+1];
   Row3:=SourceBitmap.ScanLine[cy+2];
  for x := 0 to (SourceBitmap.Width div 3)-1 do begin
     cx := x*3;
     totr := 0; totg := 0; totb := 0;
       for i := 0 to 2 do begin
         cxi := cx + i;
         totr := totr + Row1[cxi].rgbtRed + Row2[cxi].rgbtRed + Row3[cxi].rgbtRed;
         totg := totg + Row1[cxi].rgbtGreen + Row2[cxi].rgbtGreen + Row3[cxi].rgbtGreen;
         totb := totb + Row1[cxi].rgbtBlue + Row2[cxi].rgbtBlue + Row3[cxi].rgbtBlue;
       end;
       DestRow[x].rgbtRed := totr div 9;
       DestRow[x].rgbtGreen := totg div 9;
       DestRow[x].rgbtBlue := totb div 9;
   end;
  end;
 CanvasOut.CopyRect(_R,SourceBitmap.Canvas,rect(0,0,SourceBitmap.Width div 3,SourceBitmap.Height div 3));
end;

procedure BitmapPrepare(var SourceBitmap:Tbitmap; CanvasOut:TCanvas; _R:TRect);
begin
SourceBitmap.PixelFormat:=pf24bit;
SourceBitmap.Width:=(_r.Right-_r.Left)*3;
SourceBitmap.Height:=(_r.Bottom-_r.Top)*3;
SourceBitmap.Canvas.CopyRect(rect(0,0,SourceBitmap.Width,SourceBitmap.Height),Ca nvasOut,_R);
end;

procedure TForm1.Button1Click(Sender: TObject);
var _Bitmap:Tbitmap;
begin
_Bitmap:=TBitmap.Create;
 try

BitmapPrepare(_Bitmap,Image1.Picture.Bitmap.Canvas,rect(10,10,200,200)); //берем прямоугольник, в котором будет рисовать

//дальше работаем с _Bitmap.canvas как нам надо

_Bitmap.Canvas.Pen.Width:=3; //устанавливаем толщину в 3 раз больше

_Bitmap.Canvas.Ellipse(20*3,20*3,80*3,80*3);
_Bitmap.Canvas.MoveTo(50*3-1,60*3-1); //все координаты в 3 раза больше (хотя для лучшего эффекта, можно отнять еденицу - будет более смазано и качественно, главное не переборщить:))
_Bitmap.Canvas.LineTo(5*3,15*3);

_Bitmap.Canvas.Brush.Style:=bsclear;
_Bitmap.canvas.Font.Size:=_Bitmap.canvas.Font.Size*3; //тут правда косячно с размером...
_Bitmap.canvas.TextOut(2,2,"Im - super :)");

Alias(_Bitmap,Image1.Picture.Bitmap.Canvas,rect(10,10,200,200)); //вывод

 finally
_Bitmap.Free;
 end;
end;

end.


 
Ал   (2006-03-04 16:54) [2]

То есть используем доп. буфер, больший в 3 раза?

А можно ли прямым рисованием на битмапе с цветной текстурой, как в алгоритмах рисования линии, эллипса и т. п.?


 
antonn ©   (2006-03-04 17:30) [3]

Ал   (04.03.06 16:54) [2]
То есть используем доп. буфер, больший в 3 раза?

угу, можно и больше

> А можно ли прямым рисованием на битмапе с цветной
> текстурой, как в алгоритмах рисования линии, эллипса и
> т. п.?

не понял... ну в Image1 картинка, и на ней и рисуется все это дело


 
wicked ©   (2006-03-05 00:02) [4]

для Делфи есть такие варианты:
1) OpenGL - всем хорош, кроме того, что нужно заставить его рисовать в буффер в памяти.... таким свойством должна обладать, скажем, его программная реализация, но её все таки нужно умудриться включить.... это всё пишу "в теории", так как интересовался, но не делал.....
2) попробовать прикрутить что-то из того вала софта, который имеется на http://sf.net.... например, вот отсюда - http://vectorgraphics.sourceforge.net/ Недостаток - нужно искать библиотеки написанные на си (не си++) или делфи/паскале, сишные компилировать борландовским компилятором (лежит бесплатный у них на сайте), создавать модуль-обертку на делфи и линковать полученные .obj файлы..... при правильной постановке занятие это увлекательное и несложное, нужно только не забывать о соглашениях о вызове и паковании структур, буде таковые будут....
3) использовать GDI+ - там вроде есть такое... об этом хорошо у Джо (http://www.delphimaster.ru/cgi-bin/anketa.pl?id=1121389226) спросить - он делал что-то вроде....

из предложенного, думаю, оптимально будет попробовать эти пункты в обратном порядке - от 3-го к 1-му....
и не слушай никого, кто предложит Anti-Grain Geometry (http://antigrain.com) - хоть она и перекрывает GDI+ по качеству картинки, но писана она строго на си++ и к делфи её по-нормальному никак не прикрутить.... по ненормальному - писать на си++ готовые rendering pipelines, обеспечивать к ним процедурный интерфейс и помещать это дело в .dll....


 
antonn ©   (2006-03-05 07:18) [5]

wicked ©   (05.03.06 0:02) [4]
3) использовать GDI+ - там вроде есть такое... об этом хорошо у Джо (http://www.delphimaster.ru/cgi-bin/anketa.pl?id=1121389226) спросить - он делал что-то вроде....

там привязка идет к мегабайтной dll, под ХР она есть, под win2k по-умолчанию - нет. под win9x вообще не знаю, работает ли...


 
Ал   (2006-03-07 12:31) [6]

Спасибо всем за информацию!

Но хотелось бы что-нибудь более простое и не ресурсоемкое, вроде
http://alglib.sources.ru/graphics/

К сожалению, там нет полигона с заполнением.
Может, кто-нибудь подкинет полигон с заполнением, хотя бы без антиалиасинга. Дальше я бы сам попробовал.

С уважением.


 
Sapersky   (2006-03-07 15:05) [7]

http://www.g32.org/graphics32/index.html


 
DVM ©   (2006-03-12 23:02) [8]

Вот линия с антиалиазингом. Полигон можно сделать из линий.


TYPE
 TFColor  = record b,g,r:Byte end;
 PFColor  =^TFColor;

procedure SmoothLine(dc: HDC; x1, y1, x2, y2: Integer; c: TFColor);
var
 dx,dy,d,s,ci,ea,ec: Integer;
 p: tFColor;
begin
 if(y1=y2)or(x1=x2)then
 begin
   MoveToEx(dc, X1, Y1, nil);
   LineTo(dc, X2,y2);
 end
   else
 begin
   if y1>y2 then
   begin
     d:=y1; y1:=y2; y2:=d;
     d:=x1; x1:=x2; x2:=d;
   end;
   dx:=x2-x1;
   dy:=y2-y1;
   if dx>-1 then s:=1 else
   begin
     s:=-1;
     dx:=-dx;
   end;
   ec:=0;
   if dy>dx then
   begin
     ea:=(dx shl 16)div dy;
     while dy>1 do
     begin
       Dec(dy);
       d:=ec;
       Inc(ec,ea);
       ec:=ec and $FFFF;
       if ec<=d then Inc(x1,s);
       Inc(y1);
       ci:=ec shr 8;
       p.r:=GetRValue(GetPixel(DC,X1,Y1));
       p.g:=GetgValue(GetPixel(DC,X1,Y1));
       p.b:=GetbValue(GetPixel(DC,X1,Y1));
       p.b:=(p.b-c.b)*ci shr 8 + c.b;
       p.g:=(p.g-c.g)*ci shr 8 + c.g;
       p.r:=(p.r-c.r)*ci shr 8 + c.r;
       SetPixel(dc, x1, y1, Rgb(p.r, p.g, p.b));
       p.r:=GetRValue(GetPixel(DC,X1+s,Y1));
       p.g:=GetgValue(GetPixel(DC,X1+s,Y1));
       p.b:=GetbValue(GetPixel(DC,X1+s,Y1));
       p.b:=(c.b-p.b)*ci shr 8 + p.b;
       p.g:=(c.g-p.g)*ci shr 8 + p.g;
       p.r:=(c.r-p.r)*ci shr 8 + p.r;
       SetPixel(dc, x1+s, y1, Rgb(p.r, p.g, p.b));
     end;
   end else
   begin
     ea:=(dy shl 16)div dx;
     while dx>1 do
     begin
       Dec(dx);
       d:=ec;
       Inc(ec,ea);
       ec:=ec and $FFFF;
       if ec<=d then Inc(y1);
       Inc(x1,s);
       ci:=ec shr 8;
       p.r:=GetRValue(GetPixel(DC,X1,Y1));
       p.g:=GetgValue(GetPixel(DC,X1,Y1));
       p.b:=GetbValue(GetPixel(DC,X1,Y1));
       p.b:=(p.b-c.b)*ci shr 8 + c.b;
       p.g:=(p.g-c.g)*ci shr 8 + c.g;
       p.r:=(p.r-c.r)*ci shr 8 + c.r;
       SetPixel(dc, x1, y1, Rgb(p.r, p.g, p.b));
       p.r:=GetRValue(GetPixel(DC,X1,Y1+1));
       p.g:=GetgValue(GetPixel(DC,X1,Y1+1));
       p.b:=GetbValue(GetPixel(DC,X1,Y1+1));;
       p.b:=(c.b-p.b)*ci shr 8 + p.b;
       p.g:=(c.g-p.g)*ci shr 8 + p.g;
       p.r:=(c.r-p.r)*ci shr 8 + p.r;
       SetPixel(dc, x1, y1+1, Rgb(p.r, p.g, p.b));
     end;
   end;
 end;
end;



 
WondeRu ©   (2006-03-13 08:49) [9]

А GDI+ использовать религия не позволяет?



Страницы: 1 вся ветка

Текущий архив: 2006.10.01;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.032 c
15-1158041335
pasha_golub
2006-09-12 10:08
2006.10.01
Сервисы видео трансляции


15-1157985150
Ломброзо
2006-09-11 18:32
2006.10.01
Ищу tool для Oracle


15-1157875212
Marser
2006-09-10 12:00
2006.10.01
Почище Вильгельма Теля...


15-1157705486
Kolan
2006-09-08 12:51
2006.10.01
Дизайнерская задача :)


1-1155814330
Darrin
2006-08-17 15:32
2006.10.01
Создание потока, выполняющегося продолжительное время.