Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.12.2012, 20:39
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,026
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию Полупрозрачный прямоугольник

Всем здрасьте...

Вот тут бъюсь над такой проблемкой:
Есть PainBox, на который выводится картинка. Надо поверх этой картинки еще нарисовать полупрозрачный цветной прямоугольник (один цвет). Координаты прямоугольника есть (TRect). Сложность в том, что надо нарисовать его быстро. Вариант создания большого битмапа с альфа-каналом и копирования его части на картинку держу как запасной, т.к. размер прямоугольника вычисляется динамически, а еще один огромный битмап в памяти держать не очень хочется.
Есть у кого какие идеи?

ЗЫ. Ограничение - не использовать сторонних доп. библиотек, типа Graphics32 и т.п. Можно использовать DevExpress, бо как он уже в проекте используется.

Код отрисовки:
Код:
procedure TCutImageFrame.pbImagePaint(Sender: TObject);
var
  R, FaceTop, FaceBottom : TRect;
begin
  inherited;

  pbImage.Canvas.StretchDraw(FImageRect,FImage);

  If FHasPoints Then
    Begin
      R := Rect(Min(FStartPt.X,FEndPt.X),Min(FStartPt.Y,FEndPt.Y),Max(FStartPt.X,FEndPt.X),Max(FStartPt.Y,FEndPt.Y));
      pbImage.Canvas.DrawFocusRect(R);

      // Вот эти прямоугольники хочется сделать полупрозрачным цветом.
      GetFaceRects(R,FaceTop,FaceBottom);  // Вычисление координат прямоугольников
      pbImage.Canvas.DrawFocusRect(FaceTop);
      pbImage.Canvas.DrawFocusRect(FaceBottom);

    End;
end;

Последний раз редактировалось lmikle, 02.12.2012 в 20:43.
Ответить с цитированием
  #2  
Старый 02.12.2012, 20:52
Аватар для cotseec
cotseec cotseec вне форума
Активный
 
Регистрация: 16.07.2008
Сообщения: 353
Версия Delphi: D7,TDE06,RAD09
Репутация: 1443
По умолчанию

а если создать небольшой битмап, как раз под расчитанный прямоугольник, копировать из PaintBox картинку этого прямоугольника, наложить полупрозрачный прямоугольник и вывести отдельным PaintBox'ом в нужном месте над оригинальным PaintBox' ом (чтобы не затирать оригинальную картинку)
__________________
Понять, что хочет заказчик - бесценно, ведь он платит MasterCard
Ответить с цитированием
  #3  
Старый 02.12.2012, 21:23
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Точно не помню, но кажется делал так:
Код:
workcanvas.Pen.Mode:=pmMerge	;
workcanvas.Pen.Color:=clblue;
workcanvas.Brush.Color:=clblue;
//прямоугольник
Ответить с цитированием
  #4  
Старый 02.12.2012, 22:00
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Изврат но: GetDiBits обеих картинок и смешивать байты в нужной пропорции.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #5  
Старый 03.12.2012, 07:22
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,026
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от YVitaliy
Точно не помню, но кажется делал так:
Код:
workcanvas.Pen.Mode:=pmMerge	;
workcanvas.Pen.Color:=clblue;
workcanvas.Brush.Color:=clblue;
//прямоугольник

Попробую.

Цитата:
Сообщение от angvelem
Изврат но: GetDiBits обеих картинок и смешивать байты в нужной пропорции.

Как уже писал, данная операция должна производиться быстро, поэтому варант с прямой работой с пикселами скорее всего не подойдет. Слишком долго. Думал в сторону GDI/GDI+, но еще не смотрел...

Цитата:
Сообщение от cotseec
а если создать небольшой битмап, как раз под расчитанный прямоугольник, копировать из PaintBox картинку этого прямоугольника, наложить полупрозрачный прямоугольник и вывести отдельным PaintBox'ом в нужном месте над оригинальным PaintBox' ом (чтобы не затирать оригинальную картинку)

Дело в том, что координаты прямоугольника вычисляются налету. Если нужный битмап создавать заранее, то он может оказаться очень большим, чего не хотелось бы, и так в памяти висит оригинальная картинка. Если битмап создавать в процессе работы при вызове отрисовки, то чем это лучше работы с пикселами? Те же тормоза будут - пока создашь (переразмеришь битмап), пока на нем отрисуешься, а потом опять уже его отрисовывать с альфа каналом.

Собственно, думал может кто знает как отрисовать просто прямоугольник с альфа каналом. Как видно из кода, пока просто рисуется фокусный прямоугольник, что не очень наглядно...
Ответить с цитированием
  #6  
Старый 03.12.2012, 10:37
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
По умолчанию

попробовал на Gdiplus:
Код:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  graphics: GpGraphics;
  brush: GpSolidFill;
//  f, c1, c2: Int64;
begin
  PaintBox1.Canvas.Draw(0, 0, Image1.Picture.Graphic);
//  QueryPerformanceFrequency(f);
//  QueryPerformanceCounter(c1);
  GdipCreateFromHDC(PaintBox1.Canvas.Handle, graphics);
  GdipCreateSolidFill($80ffff00, brush);
  GdipFillRectangleI(graphics, brush, 0, 0, 640, 480);
  GdipDeleteBrush(brush);
  GdipDeleteGraphics(graphics);
//  QueryPerformanceCounter(c2);
//  Caption:=IntToStr((c2-c1) div (f div 1000));
end;
как-то очень медленно, 250мс
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #7  
Старый 03.12.2012, 10:52
Аватар для NumLock
NumLock NumLock вне форума
Let Me Show You
 
Регистрация: 30.04.2010
Адрес: Северодвинск
Сообщения: 5,426
Версия Delphi: 7, XE5
Репутация: 59586
Радость

отставить панику! двойная буферизация спасает ситуацию.
__________________
Пишу программы за еду.
__________________
Ответить с цитированием
  #8  
Старый 03.12.2012, 21:45
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Я через GetDIBits (точнее его предшественника) отрисовываю тень, кусок кода естественно на ассемблере.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #9  
Старый 06.12.2012, 10:17
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,026
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от angvelem
Я через GetDIBits (точнее его предшественника) отрисовываю тень, кусок кода естественно на ассемблере.

ОК, проблему решил через AlphaBlend. Надо теперь только немного оптимизировть...

Вот эта функция, мож кому пригодится. Нарыл на ExpertsExchange.
Код:
procedure TCutImageFrame.BlendRectangle(Canvas:TCanvas;R:TRect;C:TColor;MixPercent:Byte);
Var
 tmpBMP:TBitmap;
 Blend:_BLENDFUNCTION;
begin
 tmpBMP:=TBitmap.Create;
 try
  tmpBMP.Width:=1;
  tmpBMP.Height:=1;
  tmpBMP.Canvas.Pixels[0,0]:=C;
  Blend.BlendOp:=AC_SRC_OVER;
  Blend.BlendFlags:=0;
  Blend.SourceConstantAlpha:=(50+255*MixPercent) Div 100;
  Blend.AlphaFormat:=0;
  AlphaBlend(Canvas.Handle,R.Left,R.Top,R.Right-R.Left,R.Bottom-R.Top,tmpBMP.Canvas.Handle,0,0,1,1,Blend);
 finally
  tmpBMP.Free;
 end;
end;
Ответить с цитированием
  #10  
Старый 06.12.2012, 11:49
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Знакомый код, уже и не помню чем он меня тогда не устроил, а больше с ним не экспериментировал.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #11  
Старый 06.12.2012, 18:32
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,026
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от angvelem
Знакомый код, уже и не помню чем он меня тогда не устроил, а больше с ним не экспериментировал.

Ну не знаю, чем он тебя не устроил.
Отрисовка - то что хотелось.
По скорости, даже на не самой быстрой машинке (сейчас AMD Athlon M320), устраивает даже в таком виде (собственно, у меня он в отрисовке маркеров, когда юзер выделяет квадрат на картинке).
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 10:29.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter