1 (изменено: Freeman, 05.12.2020 в 16:53)

Тема: Buf2D+LibImg

Информация о Buf2D на wiki: http://wiki.kolibrios.org/wiki/Buf2d/ru
Тема о Buf2D на форуме: http://board.kolibrios.org/viewtopic.ph … =60#p28236

Я решил переделать свой пример на FreeBasic(сделанный 7 лет назад) под Delphi.
Читается файл с иконками

FilePath: PAnsiChar = '/sys/ICONS16.PNG';

Несколько иконок из файла рисуются в буфер(buf2d_bit_blt), закрашенный определённым цветом.
Буфер выводится на экран(buf2d_draw).

Можно ради интереса попробовать другой файл — ICONS32.PNG.

В результате получаем
misc.php?action=pun_attachment&item=57&download=0

program LibImg_Buf2dTest;

uses
  KolibriOS;

const
// list of format id's
  LIBIMG_FORMAT_BMP  = 1;
  LIBIMG_FORMAT_ICO  = 2;
  LIBIMG_FORMAT_CUR  = 3;
  LIBIMG_FORMAT_GIF  = 4;
  LIBIMG_FORMAT_PNG  = 5;
  LIBIMG_FORMAT_JPEG = 6;
  LIBIMG_FORMAT_TGA  = 7;
  LIBIMG_FORMAT_PCX  = 8;
  LIBIMG_FORMAT_XCF  = 9;
  LIBIMG_FORMAT_TIFF = 10;
  LIBIMG_FORMAT_PNM  = 11;
  LIBIMG_FORMAT_WBMP = 12;
  LIBIMG_FORMAT_XBM     = 13;
  LIBIMG_FORMAT_Z80  = 14;

// scale type, corresponding img_scale params
  LIBIMG_SCALE_NONE       = 0; // do not scale
  LIBIMG_SCALE_INTEGER    = 1; // scale factor ; reserved 0
  LIBIMG_SCALE_TILE       = 2; // new width    ; new height
  LIBIMG_SCALE_STRETCH    = 3; // new width    ; new height
  LIBIMG_SCALE_FIT_BOTH   = LIBIMG_SCALE_STRETCH;
  LIBIMG_SCALE_FIT_MIN    = 4; // new width    ; new height
  LIBIMG_SCALE_FIT_RECT   = LIBIMG_SCALE_FIT_MIN;
  LIBIMG_SCALE_FIT_WIDTH  = 5; // new width    ; new height
  LIBIMG_SCALE_FIT_HEIGHT = 6; // new width    ; new height
  LIBIMG_SCALE_FIT_MAX    = 7; // new width    ; new height

// interpolation algorithm
  LIBIMG_INTER_NONE      = 0;
  LIBIMG_INTER_BILINEAR  = 1;
  //LIBIMG_INTER_BICUBIC   = 2
  //LIBIMG_INTER_LANCZOS   = 3
  LIBIMG_INTER_DEFAULT   = LIBIMG_INTER_BILINEAR;

// error codes
  LIBIMG_ERROR_OUT_OF_MEMORY   = 1;
  LIBIMG_ERROR_FORMAT          = 2;
  LIBIMG_ERROR_CONDITIONS      = 3;
  LIBIMG_ERROR_BIT_DEPTH       = 4;
  LIBIMG_ERROR_ENCODER         = 5;
  LIBIMG_ERROR_SRC_TYPE        = 6;
  LIBIMG_ERROR_SCALE           = 7;
  LIBIMG_ERROR_INTER           = 8;
  LIBIMG_ERROR_NOT_INPLEMENTED = 9;
  LIBIMG_ERROR_INVALID_INPUT   = 10;

// encode flags (byte 0x02 of _common option)
  //LIBIMG_ENCODE_STRICT_SPECIFIC    = $01
  LIBIMG_ENCODE_STRICT_BIT_DEPTH    = $02;
  //LIBIMG_ENCODE_DELETE_ALPHA    = $08
  //LIBIMG_ENCODE_FLUSH_ALPHA    = $10

  IMAGE_BPP8I = 1;
  IMAGE_BPP24 = 2;
  IMAGE_BPP32 = 3;
  IMAGE_BPP15 = 4;
  IMAGE_BPP16 = 5;
  IMAGE_BPP1  = 6;
  IMAGE_BPP8G = 7;
  IMAGE_BPP2I = 8;
  IMAGE_BPP4I = 9;
  IMAGE_BPP8A = 10;

  IMAGE_IS_ANIMATED = 1;

  FLIP_VERTICAL   = 1;
  FLIP_HORIZONTAL = 2;
  FLIP_BOTH       = FLIP_VERTICAL or FLIP_HORIZONTAL;

  ROTATE_90_CW   = 1;
  ROTATE_180     = 2;
  ROTATE_270_CW  = 3;
  ROTATE_90_CCW  = ROTATE_270_CW;
  ROTATE_270_CCW = ROTATE_90_CW;

type
  PFormatsTableEntry = ^TFormatsTableEntry;
  TFormatsTableEntry = packed record
    FormatID:     LongWord;
    IsImg:        Pointer;
    Decode:       Pointer;
    Encode:       Pointer;
    Capabilities: LongWord;
  end;

  PImage = ^TImage;
  TImage = packed record
    Checksum: LongWord; // ((Width ROL 16) OR Height) XOR Data[0] ; ignored so far
    Width:    LongWord;
    Height:   LongWord;
    Next:     PImage;
    Previous: PImage;
    BPP:      LongWord; // one of IMAGE_BPP
    Data:     Pointer;
    Palette:  Pointer;  // used if BPP = (IMAGE_BPP1 or IMAGE_BPP2 or IMAGE_BPP4 or IMAGE_BPP8I)
    Extended: LongWord;
    Flags:    LongWord; // bitfield
    Delay:    LongWord; // used if Image.IsAnimated is set in Flags
  end;

  PBuf2DHeader = ^TBuf2DHeader;
  TBuf2DHeader = packed record
    Img:    Pointer;
    Left:   SmallInt;
    Top:    SmallInt;
    Width:  LongWord;
    Height: LongWord;
    Color:  LongWord;
    BPP:    Byte;
  end;


var
  LibImg, Buf2D: Pointer;
  LibImgLibInit, Buf2DLibInit: procedure;

  img_decode:  function(Data: Pointer; Length, Options: LongWord): PImage; stdcall;
  img_to_rgb2: procedure(imgData, Dst: Pointer); stdcall;
  img_destroy: procedure(imgData: Pointer); stdcall;

  buf2d_create:       procedure(var Buffer: TBuf2DHeader); stdcall;
  buf2d_draw:         procedure(var Buffer: TBuf2DHeader); stdcall;
  buf2d_delete:       procedure(var Buffer: TBuf2DHeader); stdcall;
  buf2d_create_f_img: procedure(var Buffer: TBuf2DHeader; ImgBuffer: Pointer); stdcall;
  buf2d_bit_blt:      procedure(var DstBuffer: TBuf2DHeader; X, Y: LongInt; var SrcBuffer: TBuf2DHeader); stdcall;


// --------------------------------------------------------------------------------------

function MemoryAllocate(Bytes: LongWord): Pointer; stdcall;
asm
        push ecx
        push ebx
        mov eax, 68
        mov ebx, 12
        mov ecx, Bytes
        int 64
        pop ebx
        pop ecx
end;

function MemoryReallocate(MemPtr: Pointer; Bytes: LongWord): Pointer; stdcall;
asm
        push ebx
        push ecx
        push edx
        mov eax, 68
        mov ebx, 20
        mov ecx, Bytes
        mov edx, MemPtr
        int 64
        pop edx
        pop ecx
        pop ebx
end;

function MemoryFree(MemPtr: Pointer): LongWord; stdcall;
asm
        push ecx
        push ebx
        mov eax, 68
        mov ebx, 13
        mov ecx, MemPtr
        int 64
        pop ebx
        pop ecx
end;

type
  Proc = procedure;

procedure InitLibrary(LibInit: Proc); stdcall;
asm
        pushad
        mov eax, offset MemoryAllocate
        mov ebx, offset MemoryFree
        mov ecx, offset MemoryReallocate
        mov edx, offset @dll_load
        call LibInit
        popad
        jmp @DllInit_exit
  @dll_load:
        push ebp
        mov  ebp, esp
        push ebx
        push esi
        push edi
        mov  esi, [ebp + 8]
  @next_lib:
        mov  edx, [esi]
        or   edx, edx
        jz  @exit
        push esi
        mov  esi, [esi + 4]
        mov  edi, offset @lib_name
  @b:
        lodsb
        stosb
        or al, al
        jnz  @b
        push offset @lib_path
        call LoadLibrary
        or  eax, eax
        jz  @fail
        mov  ecx, [eax]
        cmp  dword ptr [ecx], 'lib_'
        jne  @skip_init
        cmp  dword ptr [ecx + 4], 'init'
        jne  @skip_init
        push dword ptr [eax + 4]
        call InitLibrary
  @skip_init:
        mov  ecx, eax
        mov  ebx, edx
        test edx, edx
        jz  @done
  @next:
        mov  eax, [ebx]
        test eax, eax
        jz  @done
        push eax
        push ecx
        call GetProcAddress
        or eax, eax
        jz  @f
        mov [ebx], eax
        add ebx, 4
        jmp  @next
  @f:
        mov dword ptr [esp], eax
  @done:
        pop esi
        add esi, 8
        jmp  @next_lib
  @exit:
        xor eax, eax
        jmp @return
  @fail:
        pop esi
        inc eax
  @return:
        pop edi
        pop esi
        pop ebx
        pop ebp
        ret 4
  @lib_path: db '/sys/lib/'
  @lib_name: db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  @DllInit_exit:
end;

// --------------------------------------------------------------------------------------

var
  FileAttributes: TFileAttributes;
  BytesRead: LongWord;
  FilePath: PAnsiChar = '/sys/ICONS16.PNG';

  imgFile: Pointer;
  imgFileSize: LongWord;
  imgData: PImage;
  ImgWidth, ImgHeight: LongWord;
  imgBuffer: Pointer;

  WndLeft, WndTop: LongInt;
  WndWidth: LongWord = 500;
  WndHeight: LongWord = 300;

  PaddingX: LongWord;
  PaddingY: LongWord = 5;
  MarginX:  LongWord = 8;
  MarginY:  LongWord = 10;

  buf2dImageBuffer, buf2dItemBuffer: TBuf2DHeader;
  Icons: Pointer;

function RGB(R, G, B: Byte): LongWord;
begin
  Result := R shl 16 or G shl 8 or B;
end;

procedure DrawItem(X, Y: LongInt; Index: LongWord; BackColor: LongWord);
begin
  with buf2dItemBuffer do
  begin
    width    := 100;
    height   := PaddingY * 2 + ImgWidth;
    left     := x;
    top      := y;
    color    := BackColor;
    bpp      := 24;
    PaddingX := (width - ImgWidth) div 2;
  end;
  buf2dImageBuffer.Img := Pointer(ImgWidth * ImgWidth * 3 * Index  + LongWord(Icons));
  buf2d_create(buf2dItemBuffer);
  buf2d_bit_blt(buf2dItemBuffer, PaddingX, PaddingY, buf2dImageBuffer);
  buf2d_draw(buf2dItemBuffer);
  buf2d_delete(buf2dItemBuffer);
end;

procedure On_Redraw;
var
 Index: LongWord;
 X, Y: LongInt;
begin
  BeginDraw;
  DrawWindow(WndLeft, WndTop, WndWidth, WndHeight, 'LibImg_Buf2d Test', $00FAFBFC,
    WS_SKINNED_SIZABLE + WS_CLIENT_COORDS + WS_CAPTION, CAPTION_MOVABLE);
  Index := 0;
  X := 20;
  While X <= 400 do
  begin
    Y := 10;
    While Y <= 200 do
    begin
      DrawItem(X, Y, Index, RGB(Y mod 256, 10 * Index mod 256, X mod 256));
      Inc(index);
      Inc(Y, buf2dItemBuffer.Height + MarginY);
    end;
    Inc(X, buf2dItemBuffer.Width + MarginX);
  end;
  EndDraw;
end;

begin
  LibImg        := LoadLibrary('/sys/lib/libimg.obj');
  LibImgLibInit := GetProcAddress(LibImg, 'lib_init');
  img_decode    := GetProcAddress(LibImg, 'img_decode');
  img_to_rgb2   := GetProcAddress(LibImg, 'img_to_rgb2');
  img_destroy   := GetProcAddress(LibImg, 'img_destroy');

  Buf2D              := LoadLibrary('/sys/lib/buf2d.obj');
  buf2dLibInit       := GetProcAddress(Buf2D, 'lib_init');
  buf2d_create       := GetProcAddress(Buf2D, 'buf2d_create');
  buf2d_draw         := GetProcAddress(Buf2D, 'buf2d_draw');
  buf2d_delete       := GetProcAddress(Buf2D, 'buf2d_delete');
  buf2d_create_f_img := GetProcAddress(Buf2D, 'buf2d_create_f_img');
  buf2d_bit_blt      := GetProcAddress(Buf2D, 'buf2d_bit_blt');

  InitLibrary(LibImgLibInit);
  InitLibrary(Buf2DLibInit);

  GetFileAttributes(FilePath, FileAttributes);
  imgFileSize := FileAttributes.Size;
  imgFile := HeapAllocate(imgFileSize);
  ReadFile(FilePath, imgFile^, imgFileSize, 0, BytesRead);
  imgData := img_decode(imgFile, imgFileSize, 0);
  HeapFree(imgFile);
  ImgWidth := imgData.Width;
  ImgHeight := imgData.Height;
  imgBuffer := HeapAllocate(ImgWidth * ImgHeight * 3);
  img_to_rgb2(imgData, imgBuffer);
  img_destroy(imgData);

  with buf2dImageBuffer do
  begin
    Width  := ImgWidth;
    Height := ImgHeight;
    BPP    := 24;
    buf2d_create_f_img(buf2dImageBuffer, imgBuffer);
    Height := ImgWidth;
    Icons  := Img;
  end;
  HeapFree(imgBuffer);

  with GetScreenSize do
  begin
    WndLeft := (Width - WndWidth) div 2;
    WndTop := (Height - WndHeight) div 2;
  end;

  while True do
    case WaitEvent of
      REDRAW_EVENT:
        On_Redraw;
      KEY_EVENT:
        GetKey;
      BUTTON_EVENT:
        Break;
    end;
end.
Post's attachments

libimg_buf2d_test.PNG, 11.7 Кб, 501 x 301
libimg_buf2d_test.PNG 11.7 Кб, 80 скачиваний с 2020-09-24