unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls,
StdCtrls, SDL2, SDL2_image, Math;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
OpenDialog1: TOpenDialog;
Panel1: TPanel;
Panel2: TPanel;
StatusBar1: TStatusBar;
procedure Button1Click(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormShow(Sender: TObject);
private
SDLWindow: PSDL_Window;
SDLRenderer: PSDL_Renderer;
CurrentTexture: PSDL_Texture;
procedure InitializeSDL;
procedure ShutdownSDL;
procedure LoadAndDisplayImage(const FileName: string);
procedure RenderImage;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
procedure TForm1.Button1Click(Sender: TObject);
begin
if OpenDialog1.Execute then
LoadAndDisplayImage(OpenDialog1.FileName);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
ShutdownSDL;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
RenderImage;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
InitializeSDL;
end;
procedure TForm1.InitializeSDL;
begin
if SDL_Init(SDL_INIT_VIDEO) < 0 then
raise Exception.Create('Could not initialize SDL: ' + SDL_GetError);
SDLWindow := SDL_CreateWindowFrom(Pointer(Panel1.Handle));
if SDLWindow = nil then
raise Exception.Create('Could not create SDL window: ' + SDL_GetError);
SDLRenderer := SDL_CreateRenderer(SDLWindow, -1, SDL_RENDERER_ACCELERATED);
if SDLRenderer = nil then
raise Exception.Create('Could not create SDL renderer: ' + SDL_GetError);
if IMG_Init(IMG_INIT_PNG or IMG_INIT_JPG) = 0 then
raise Exception.Create('Could not initialize SDL_image: ' + IMG_GetError);
end;
procedure TForm1.ShutdownSDL;
begin
if CurrentTexture <> nil then
SDL_DestroyTexture(CurrentTexture);
if SDLRenderer <> nil then
SDL_DestroyRenderer(SDLRenderer);
if SDLWindow <> nil then
SDL_DestroyWindow(SDLWindow);
IMG_Quit;
SDL_Quit;
end;
procedure TForm1.LoadAndDisplayImage(const FileName: string);
begin
// Clean up the old texture if it exists
if CurrentTexture <> nil then
SDL_DestroyTexture(CurrentTexture);
// Load the new image as a texture
CurrentTexture := IMG_LoadTexture(SDLRenderer, PChar(FileName));
if CurrentTexture = nil then
raise Exception.Create('Could not load texture: ' + IMG_GetError);
// Render the image to fit the new size
RenderImage;
end;
procedure TForm1.RenderImage;
var
SrcRect, DstRect: TSDL_Rect;
ImgWidth, ImgHeight: Integer;
PanelWidth, PanelHeight: Integer;
AspectRatio: Double;
begin
if CurrentTexture = nil then
Exit;
// Get image dimensions
SDL_QueryTexture(CurrentTexture, nil, nil, @ImgWidth, @ImgHeight);
// Get panel dimensions
PanelWidth := Panel1.Width;
PanelHeight := Panel1.Height;
// Calculate aspect ratio to fit the image proportionally
AspectRatio := Min(PanelWidth / ImgWidth, PanelHeight / ImgHeight);
DstRect.w := Round(ImgWidth * AspectRatio);
DstRect.h := Round(ImgHeight * AspectRatio);
DstRect.x := (PanelWidth - DstRect.w) div 2;
DstRect.y := (PanelHeight - DstRect.h) div 2;
// Render the image
SDL_RenderClear(SDLRenderer);
SDL_RenderCopy(SDLRenderer, CurrentTexture, nil, @DstRect);
SDL_RenderPresent(SDLRenderer);
end;
end.