Форум: "Начинающим";
Текущий архив: 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