Простая обработка графики

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Простая обработка графики

Сообщение avi9526 » 05.08.2011 18:34:18

Раньше пытался что-то делать в delphi, там не было того что надо, пришлось писать самому... в lazarus'е пока тоже не нашел (потому, собственно и пишу).
Нужно:
1. Функции чтобы нарисовать один tbitmap на другом с учетом альфа канала
2. Функции чтобы нарисовать один tbitmap на другом с учетом прозрачности заданной числом?
3. Функции чтобы узнать адрес самих данных (в delphi была tbutton.scanline, а в lazarus'e вроде нету)

хотел старые "наработки" использовать, но там было немного столь любимого мною ассемблера :?
Код: Выделить всё
procedure TransparentBitBltC(Dest: TBitmap; PasteLeft, PasteTop: Integer; Source: TBitmap;
          CopyLeft, CopyTop, CopyWidth, CopyHeight: Integer);
var
    DLine,SLine,AK:integer;
    DLeft,Width,Height:integer;
    SLeft:integer;
    D,S:PAC;
    DBounds,SBounds,CopyBounds,PasteBounds:TBounds;
begin
Dest.PixelFormat:=pf32bit;
Source.PixelFormat:=pf32bit;

DBounds:=GetBounds(0,0,Dest.Width,Dest.Height);
SBounds:=GetBounds(0,0,Source.Width,Source.Height);
PasteBounds:=GetBounds(PasteLeft,PasteTop,CopyWidth,CopyHeight);
CopyBounds:=GetBounds(CopyLeft,CopyTop,CopyWidth,CopyHeight);
PasteBounds:=BoundsAnd(PasteBounds,DBounds);
PasteBounds.Left:=PasteBounds.Left-PasteLeft;
PasteBounds.Top:=PasteBounds.Top-PasteTop;
CopyBounds:=BoundsAnd(CopyBounds,SBounds);
CopyBounds.Left:=CopyBounds.Left-CopyLeft;
CopyBounds.Top:=CopyBounds.Top-CopyTop;
PasteBounds:=BoundsAnd(PasteBounds,CopyBounds);
if (PasteBounds.Width<=0)OR(PasteBounds.Height<=0)
then
  Exit;
{---------------------------------}
DLine:=Dest.Width*4;  //Оскільки формат pf32bit
SLine:=Source.Width*4;//то наодин піксель - 4 байти (Opaque,Red,Green,Blue)
D:=Dest.ScanLine[PasteBounds.Top+PasteTop];
S:=Source.ScanLine[PasteBounds.Top+CopyTop];
SLeft:=PasteBounds.Left+CopyLeft;
DLeft:=PasteBounds.Left+PasteLeft;
Width:=4*(SLeft+PasteBounds.Width); //Економимо на змінних, використаємо замість Right
Height:=PasteBounds.Height;
DLeft:=4*DLeft;
SLeft:=4*SLeft;
asm
    XOR EAX,EAX //for eax:=0 to Height-1 do
@B1:CMP EAX,Height
    JAE @E1     //if >= then goto @e1
    PUSH EAX    //збереження кроку циклу
{---------------------------------}
      MOV ECX,DLeft
      MOV EBX,SLeft
  @B2:CMP EBX,Width
      JAE @E2
      PUSH EBX //збереження
      PUSH ECX //кроків циклу
{---------------------------------}
      ADD ECX,D
      ADD EBX,S
     
      MOV DH,[EBX+3]

      XOR EAX,EAX //рівносильно "mov eax,0" але швидше
      MOV AL,[EBX]
      MUL DH
      MOV AK,EAX
      XOR EAX,EAX
      MOV AL,[ECX]
      MOV DL,DH
      NOT DL  //теж саме що й 255-BL
      MUL DL
      ADD EAX,AK
      MOV DL,255
      DIV DL
      MOV [ECX],AL

      XOR EAX,EAX
      MOV AL,[EBX+1]
      MUL DH
      MOV AK,EAX
      XOR EAX,EAX
      MOV AL,[ECX+1]
      MOV DL,DH
      NOT DL
      MUL DL
      ADD EAX,AK
      MOV DL,255
      DIV DL
      MOV [ECX+1],AL

      XOR EAX,EAX
      MOV AL,[EBX+2]
      MUL DH
      MOV EBX,EAX   //значення в EBX більше не потрібне
      XOR EAX,EAX
      MOV AL,[ECX+2]
      NOT DH
      MUL DH
      ADD EAX,EBX
      MOV DL,255
      DIV DL
      MOV [ECX+2],AL
{---------------------------------}
      POP ECX
      POP EBX
      ADD EBX,4
      ADD ECX,4
      JMP @B2
  @E2:

    MOV EAX,D
    SUB EAX,DLine
    MOV D,EAX
    MOV EAX,S
    SUB EAX,SLine
    MOV S,EAX
{---------------------------------}
    POP EAX
    INC EAX
    JMP @B1
@E1:
end;
end;


Что нибудь посоветуете? Спасибо!
Аватара пользователя
avi9526
новенький
 
Сообщения: 16
Зарегистрирован: 25.08.2010 17:10:26

Re: Простая обработка графики

Сообщение MageSlayer » 05.08.2011 19:36:33

TLazIntfImage.GetDataLineStart
MageSlayer
постоялец
 
Сообщения: 216
Зарегистрирован: 07.09.2006 12:30:44


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 13

Рейтинг@Mail.ru