Тема: 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.
В результате получаем
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.