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

Тема: LibImg

Информация на wiki: http://wiki.kolibrios.org/wiki/Libs-dev/libimg/ru
Тема на форуме: http://board.kolibrios.org/viewtopic.ph … amp;t=1728

Этот пример показывает использование библиотеки LibImg.
Загружается файл FilePath с изображением.
Изображение декодируется.
Затем изображение переводится в массив пикселей RGB.
И выводится на экран с помощью функции DrawImage.

Вообще для вывода изображения существует библиотечная функция  img_draw, также существует функция для масштабирования img_scale.
Но иногда бывает нужно не только вывести изображение на экран.
Например, может понадобиться сделать какую-то трансформацию, применить какой-нибудь фильтр или вообще вывести это изображение в другой буфер.

На данный момент директория '/sys' содержит файлы 'TOOLBAR.PNG' и 'NOTIFY3.PNG'.
Эти файлы можно загрузить, указав соответствующее значение FilePath

  FilePath: PAnsiChar = '/sys/TOOLBAR.PNG';
  //FilePath: PAnsiChar = '/sys/NOTIFY3.PNG';

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

program LibImgTest;

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;

var
  LibImg: Pointer;
  LibImgLibInit: 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;

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

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/TOOLBAR.PNG';
  //FilePath: PAnsiChar = '/sys/NOTIFY3.PNG';

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

  WndLeft, WndTop: LongInt;
  WndWidth: LongWord = 300;
  WndHeight: LongWord = 300;
    
procedure On_Redraw;
begin
  BeginDraw;
  DrawWindow(WndLeft, WndTop, WndWidth, WndHeight, 'LibImg Test', $00FAFBFC,
    WS_SKINNED_SIZABLE + WS_CLIENT_COORDS + WS_CAPTION, CAPTION_MOVABLE);
  DrawImage(imgBuffer^, 10, 5, ImgWidth, ImgHeight);
  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');

  InitLibrary(LibImgLibInit);

  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 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_test1.PNG, 5.59 Кб, 301 x 301
libimg_test1.PNG 5.59 Кб, 81 скачиваний с 2020-09-24 

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