Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2009.12.13;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.52 MB
Время: 0.007 c
15-1255893240
Kostafey
2009-10-18 23:14
2009.12.13
SQL: Размышления о хаосе и порядке.


15-1255207930
Суслик_
2009-10-11 00:52
2009.12.13
Клауд компьютинг в массы...


2-1256729336
Morgan128
2009-10-28 14:28
2009.12.13
Как отследить действия над сторонним окном?


2-1256364118
Pascal96
2009-10-24 10:01
2009.12.13
Подскажите, пожалуйста )))


2-1256864358
Тимофей
2009-10-30 03:59
2009.12.13
скриншот заданной области





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский