Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Звук, графика и видео > обрезать картинку по кругу


Автор: Тьма 23.8.2006, 11:26
доброго времени суток

сабж.
картинка квадратная, диаметр круга равен стороне квадрата.
я вижу два решения этой проблемы, и они мне не нравятся:

1 все точки, которые находятся вне круга делать прозрачными путем перебора каждой точки рисунка (хоть рисунок небольшой, но все равно медленный способ)

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

Автор: Alexeis 23.8.2006, 13:54
Для рисования непрямоугльных областей, удобно работать с регионами.
Вот пример:
Берем чистый проет бросаем на него кнопку, панельку, а на панельку paintbox. Кидаем Image на форму и грузим в нее картинку.
теперь рисуем
1) создаем регион. Он может быть прямоугольным, эллиптическим, прямоугольником с закруглеными краями или любой комбинацией перечисленных.
пример:
Код

var
  rgn : HRGN;
begin
  rgn := CreateEllipticRgn(0, 0, 100, 100);

2)Устанавливаем область вывода контекста в виде нашего региона
Код

SelectClipRgn(pb1.Canvas.Handle, rgn);
//и сдвигаем ее в нужную позицию
 OffsetClipRgn(pb1.Canvas.Handle, 50, 50);

3)Рисуем в указаной области 
Код

pb1.Canvas.Draw(0,0, img1.Picture.Bitmap);

4)Устанавливаем стандартную область вывода
Код

SelectClipRgn(pb1.Canvas.Handle, 0);

5)Уничтожаем регион
Код

DeleteObject(rgn);


Вот пример целиком
Код

unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    btn1: TButton;
    pb1: TPaintBox;
    img1: TImage;
    pnl1: TPanel;
    procedure btn1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.btn1Click(Sender: TObject);
var
  rgn : HRGN;
begin
  rgn := CreateEllipticRgn(0, 0, 100, 100);
  SelectClipRgn(pb1.Canvas.Handle, rgn);
  OffsetClipRgn(pb1.Canvas.Handle, 50, 50);
  pb1.Canvas.Draw(0,0, img1.Picture.Bitmap);
  SelectClipRgn(pb1.Canvas.Handle, 0);
  DeleteObject(rgn);
end;

end.

Автор: Тьма 23.8.2006, 14:25
интерестно, спасибо, с меня плюс


Код

SelectClipRgn(pb1.Canvas.Handle, 0);

насколько я понимаю это можно использовать и для невидимых битмапов?

Автор: Alexeis 23.8.2006, 15:53
Цитата(Тьма @  23.8.2006,  14:25 Найти цитируемый пост)
насколько я понимаю это можно использовать и для невидимых битмапов?

Конечно, ведь все графические контексты эквивалентны.

Любопытно, что на компотенте TForm не удается рисовать такие регионы (что-то он блокирует), а вот на KOL форме, легко.

Вот примерчик на KOL (хотя скорее на API вышло smile )

Код

var
  bmp : HBITMAP;
  bmpdc  : HDC;
  rgn : HRGN;
  pDC : HDC;

begin
  pDC := GetDC(form.Handle);

  bmp := Windows.LoadBitmap(HInstance, 'BM1');
  bmpdc := CreateCompatibleDC(pDC);
  SelectObject(bmpdc, bmp);

  rgn := CreateEllipticRgn(0, 0, 100, 100);
  SelectClipRgn(pDC, rgn);
  OffsetClipRgn(pDC, 50, 50);

  BitBlt(pDC, 0, 0, 300, 300,
         bmpdc, 0, 0, SRCCOPY);

  SelectClipRgn(pDC, 0);
  DeleteObject(rgn);
  DeleteObject(bmpdc);
  ReleaseDC(pDC, form.Handle);
  DeleteObject(bmp); 
end;


прикрепляю экзешник (если вдруг KOL не установлено)

Автор: Alexeis 23.8.2006, 16:11
А вот вывод на bitmap
Код

var
  rgn : HRGN;
  b : TBitmap;
begin
  b := TBitmap.Create;
  b.Width := 120;
  b.Height := 120;
  rgn := CreateEllipticRgn(0, 0, 100, 100);
  SelectClipRgn(b.Canvas.Handle, rgn);
  b.Canvas.Draw(0,0, img1.Picture.Bitmap);
  SelectClipRgn(b.Canvas.Handle, 0);
  DeleteObject(rgn);
  Canvas.Draw(10,10, b);
  b.Free
end;

Автор: Тьма 23.8.2006, 16:21
ну я так и думал, спасибо

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)