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

Вниз

GDI как "затенить" заданый прямоугольник ?   Найти похожие ветки 

 
Инна   (2009-10-20 20:49) [0]

есть канва, на ней чтото нарисовано, как нарисовать прозрачное выделение прямоугольной области, с минимальными затратами ?


 
DVM ©   (2009-10-20 20:57) [1]


> Инна   (20.10.09 20:49)  

Windows окно сверху кладет полупрозрачное.


 
Омлет   (2009-10-20 21:00) [2]

Понизить яркость нужной области. Но надо работать с растром.


 
Б   (2009-10-20 21:00) [3]

Windows.AlphaBlend


 
Инна   (2009-10-20 21:02) [4]

ну ё-маё...
при чем тут проводник ?
написала же GDI !!!


 
Инна   (2009-10-20 21:04) [5]

чтото в районе PatBlt


 
DVM ©   (2009-10-20 21:04) [6]


> написала же GDI !!!

А проводник через DirectX что ли делает?

Через гди проходи сканлайном по пикселям и вычитай из каждой цветовой составляющей одно и то же число. Яркость и понизится.


 
Игорь Шевченко ©   (2009-10-20 21:14) [7]

BitBlt, в качестве источника использовать шахматный битмап (55) нужного размера, в качестве ROP использовать SRCPAINT


 
Инна   (2009-10-20 21:16) [8]


> А проводник через DirectX что ли делает?

так и знала , что будет ответ в стиле "окна тоже на GDI" lol


 
Игорь Шевченко ©   (2009-10-20 21:17) [9]

Вру, не SRCPAINT, MERGECOPY


 
Инна   (2009-10-20 21:19) [10]


> Игорь Шевченко

вот это и нужно :)
можно еще браш сделать и залить PatBlt
может есть рабочий сцылка ?


 
Игорь Шевченко ©   (2009-10-20 21:22) [11]


> может есть рабочий сцылка ?


Фэнь Юань, "Программирование графики для Windows" - там это и рассказывается. Ссылки нет, самому пример писать лень


 
Игорь Шевченко ©   (2009-10-20 21:25) [12]

Битмар создается просто:

function CreateShadowBitmap (AWidth, AHeight: Integer): TBitmap;
var
 X, Y : Integer;
begin
 Result := TBitmap.Create;
 with Result do begin
   Width := AWidth;
   Height := AHeight;
   with Canvas do
   begin
     Brush.Color := clWhite;
     FillRect(Rect(0, 0, Width, Height));
     for Y := 0 to Pred(AHeight) do
       for X := 0 to Pred(AWidth) do
         if (Y mod 2) = (X mod 2) then  { toggles between even/odd pixles }
           Pixels[X, Y] := clBlack;         { on even/odd rows }
    end;
 end;
end;


 
Омлет   (2009-10-20 21:29) [13]

У меня такое ощущение, что здесь http://www.soft-gems.net/index.php?option=com_content&task=view&id=12&Itemid=33  именно то, что вам нужно. Если еще учесть вопрос про дерево каталогов, то первый скриншот по ссылке очень кстати (и дерево есть, и выделение прямоугольника). Тот компонент использует свою функцию AlphaBlend, исходники открыты, можно достать.


 
Омлет   (2009-10-20 21:32) [14]

> Игорь Шевченко ©   (20.10.09 21:25) [12]
> Pixels[X, Y] := clBlack;


Ой, только не Pixels )


 
Инна   (2009-10-20 21:58) [15]


> Омлет

нее дерево не причом, оно на другую тему

я ПРОСТО рисую на канве и нужно выделить область
сейчас использую PatBlt(Canvas.handle,0,0,х,у,DSTINVERT)
но это инверсия, а хочется затемнение,обесчвечивание или гдето\както
и чтоб проще и быстрей :)


 
Игорь Шевченко ©   (2009-10-20 22:01) [16]

Омлет   (20.10.09 21:32) [14]

Один раз создать объект и использовать - какая разница, Pixels, не pixels


 
DVM ©   (2009-10-20 22:09) [17]


> Игорь Шевченко ©   (20.10.09 22:01) [16]


> Один раз создать объект и использовать - какая разница,
> Pixels, не pixels

Если предполагается использовать его для выделения, то получается и не один раз. Он же тянуться за мышью должен?

А не проще ли создать нужную кисть из 2*2 пикселов и залить ею нужный прямоугольник?


 
Игорь Шевченко ©   (2009-10-20 22:12) [18]


> Если предполагается использовать его для выделения, то получается
> и не один раз. Он же тянуться за мышью должен?


Создать большой объект, рисовать только его нужную часть в нужной позиции. BitBlt как раз это и умеет и PatBlt как частный случай BitBlt


 
Омлет   (2009-10-20 22:14) [19]

> Инна   (20.10.09 21:58) [15]

Обычно при рисовании используется временный Bitmap. Область на нем затенить очень просто (через ScanLine) без всяких дополнительных масок и winapi.


 
DVM ©   (2009-10-20 22:24) [20]


> Омлет   (20.10.09 22:14) [19]


> Обычно при рисовании используется временный Bitmap.

Если область выделения не должна накрывать другие оконные контролы только. Иначе нужно либо полупрозрачное окно или иммитация полупрозрачности.


 
Инна   (2009-10-20 22:29) [21]

нету никаких контролов, буфер битмап который потом блитится на голую панель
вот нашла http://www.rsdn.ru/forum/winapi/1198349.flat.aspx
но там нипанятна :(


 
DVM ©   (2009-10-20 22:43) [22]

Вот тебе переделывай под себя:

unit Unit1;

interface

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

type
 TForm1 = class(TForm)
   btn1: TButton;
   procedure btn1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   Bitmap1:TBitmap;
 end;

function AlphaBlend(
 hdcDest:HDC;
 nXOriginDest,
 nYOriginDest,
 nWidthDest,
 nHeightDest:integer;
 hdcSrc:HDC;
 nXOriginSrc,
 nYOriginSrc,
 nWidthSrc,
 nHeightSrc:integer;
 blendFunction:TBLENDFUNCTION
) : boolean;stdcall; external "Msimg32.dll";

var
 Form1: TForm1;

implementation

{$R *.dfm}

procedure Blend(Alpha: integer; Dest: TForm; RDest:Trect; Source: Tbitmap; RSource: TRect);
var
 SourceDC, DestDC: HDC;
 TB: TBLENDFUNCTION;
 bres: boolean;
begin
 TB.BlendOp:=0;
 TB.BlendFlags:=0;
 TB.SourceConstantAlpha:=alpha;
 TB.AlphaFormat:=0;
  bres:=alphablend(
   dest.canvas.handle,rdest.left,rdest.top,
   rdest.right-rdest.left,rdest.bottom-rdest.top,
 source.canvas.handle,
 rsource.left,rsource.top,
   rsource.right-rsource.left,rsource.bottom-rsource.top,
 TB);
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
Bitmap1:=TBitmap.Create;
Bitmap1.Width:=60;
Bitmap1.Height:=60;
Bitmap1.Canvas.Brush.Color:=clblue;
Bitmap1.Canvas.Rectangle(Rect(0,0,60,60));
blend(120,self,Bitmap1.Canvas.ClipRect,Bitmap1,Bitmap1.Canvas.ClipRect);
self.Canvas.Pen.Color:=clBlack;
self.Canvas.Polyline([Point(0,0),Point(60,0),Point(60,60),Point(0,60), Point(0,0)]);
Bitmap1.Free;
end;

end.



 
Омлет   (2009-10-20 22:49) [23]

В качестве простого примера для ScanLine:


procedure ShadowRect(Bmp: TBitmap; const R: TRect; Value: Byte);
var
 X, Y: Integer;
 P: pRGBTriple;
begin
 Bmp.PixelFormat := pf24Bit;
 for Y := R.Top to R.Bottom do
 begin
   P := Bmp.ScanLine[Y];
   Inc(P, R.Left);
   for X := R.Left to R.Right do
   begin
     with P^ do
     begin
       rgbtBlue := Max(0, rgbtBlue - Value);
       rgbtGreen := Max(0, rgbtGreen - Value);
       rgbtRed := Max(0, rgbtRed - Value);
     end;
     Inc(P);
   end;
 end;
end;


Но лучше, наверное, смешивать с цветом.


 
Игорь Шевченко ©   (2009-10-20 23:21) [24]

Наврал-таки я с растровой операцией, должна быть SRCAND для затенения или SRCPAINT для осветления выделенной области.

Где-то так выходит:

unit main;

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

type
 TfMain = class(TForm)
   procedure FormCreate(Sender: TObject);
   procedure FormPaint(Sender: TObject);
   procedure FormMouseDown(Sender: TObject; Button: TMouseButton;
     Shift: TShiftState; X, Y: Integer);
 private
   FImage: TBitmap;
   FShadow: TBitmap;
   FOrigin: TPoint;
   FCursorClicked: TPoint;
 end;

var
 fMain: TfMain;

implementation

{$R *.dfm}

function CreateShadowBitmap (AWidth, AHeight: Integer): TBitmap;
var
X, Y : Integer;
begin
Result := TBitmap.Create;
with Result do begin
  Width := AWidth;
  Height := AHeight;
  with Canvas do
  begin
    Brush.Color := clWhite;
    FillRect(Rect(0, 0, Width, Height));
    for Y := 0 to Pred(AHeight) do
      for X := 0 to Pred(AWidth) do
        if (Y mod 2) = (X mod 2) then  { toggles between even/odd pixles }
          Pixels[X, Y] := clBlack;         { on even/odd rows }
   end;
end;
end;

procedure TfMain.FormCreate(Sender: TObject);
begin
 FImage := TBitmap.Create;
 FImage.LoadFromFile("image.bmp");
 FShadow := CreateShadowBitmap(FImage.Width, FImage.Height);
end;

procedure TfMain.FormMouseDown(Sender: TObject; Button: TMouseButton;
 Shift: TShiftState; X, Y: Integer);
begin
 if (Button = mbLeft) and (Shift = [ssLeft]) then
 begin
   if FOrigin.X = 0 then
     FOrigin := Point(X,Y)
   else
   begin
     FCursorClicked := Point(X,Y);
     Invalidate;
   end;
 end;
end;

procedure TfMain.FormPaint(Sender: TObject);
var
 ShadowedRect: TRect;
 Worker: TPoint;
begin
 Canvas.Draw(20, 20, FImage);
 if (FOrigin.X <> 0) and (FCursorClicked.X <> 0) then
 begin
   if (FOrigin.X > FCursorClicked.X) or (FOrigin.Y > FCursorClicked.Y) then
   begin
     //Swap points
     Worker := FOrigin;
     FOrigin := FCursorClicked;
     FCursorClicked := Worker;
   end;
   ShadowedRect := Rect(FOrigin, FCursorClicked);
   BitBlt(Canvas.Handle, FOrigin.X, FOrigin.Y, FCursorClicked.X - FOrigin.X,
     FCursorClicked.Y - FOrigin.Y, FShadow.Canvas.Handle, 0, 0, SRCAND);
   FOrigin := Point(0,0);
   FCursorClicked := Point(0,0);
 end;
end;

end.


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


 
Игорь Шевченко ©   (2009-10-20 23:22) [25]

и переменная лишняя ShadowedRect.

После отрисовки координаты области сбрасываются


 
Инна   (2009-10-21 11:20) [26]


> Омлет


> Игорь Шевченко

спасибо работает, но хотелось бы попроще конечно


 
Инна   (2009-10-21 13:16) [27]


> Омлет

респект

> Игорь Шевченко

очень долго креатица, и много лишнего



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

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

Наверх




Память: 0.54 MB
Время: 0.014 c
3-1231501515
Виталий Панасенко
2009-01-09 14:45
2009.12.13
Ошибка с CHAR_SET WIN1251


2-1256168975
TIF
2009-10-22 03:49
2009.12.13
Отобразить кнопку на панели задач (TaskBar)


2-1256798499
Knight
2009-10-29 09:41
2009.12.13
Как нарисовать прогрессбар градиентом?


15-1255284553
Denis123
2009-10-11 22:09
2009.12.13
Проверка сложности пaроля


4-1225268964
XshStasX
2008-10-29 11:29
2009.12.13
интересний результат с ловушкой на WH_SHELL